distribution-nixpkgs 1.6.2 → 1.7.0
raw patch · 7 files changed
+545/−49 lines, 7 filesdep +directorydep −splitdep ~Cabaldep ~language-nixPVP ok
version bump matches the API change (PVP)
Dependencies added: directory
Dependencies removed: split
Dependency ranges changed: Cabal, language-nix
API changes (from Hackage documentation)
- Distribution.Nixpkgs.Meta: allKnownPlatforms :: Set Platform
+ Distribution.Nixpkgs.Meta: NixpkgsPlatformGroup :: Identifier -> NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: NixpkgsPlatformSingle :: Platform -> NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: badPlatforms :: Lens' Meta (Maybe (Set NixpkgsPlatform))
+ Distribution.Nixpkgs.Meta: data NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: instance Control.DeepSeq.NFData Distribution.Nixpkgs.Meta.NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: instance GHC.Classes.Eq Distribution.Nixpkgs.Meta.NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: instance GHC.Classes.Ord Distribution.Nixpkgs.Meta.NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: instance GHC.Generics.Generic Distribution.Nixpkgs.Meta.NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: instance GHC.Show.Show Distribution.Nixpkgs.Meta.NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: instance Text.PrettyPrint.HughesPJClass.Pretty Distribution.Nixpkgs.Meta.NixpkgsPlatform
+ Distribution.Nixpkgs.Meta: mainProgram :: Lens' Meta (Maybe String)
+ Distribution.Nixpkgs.Meta: nixpkgsPlatformFromString :: String -> Maybe NixpkgsPlatform
+ Language.Nix.PrettyPrinting: listattrDoc :: String -> Doc -> [Doc] -> Doc
+ Language.Nix.PrettyPrinting: toAscListSortedOn :: (a -> String) -> Set a -> [a]
- Distribution.Nixpkgs.Meta: hydraPlatforms :: Lens' Meta (Set Platform)
+ Distribution.Nixpkgs.Meta: hydraPlatforms :: Lens' Meta (Maybe (Set NixpkgsPlatform))
- Distribution.Nixpkgs.Meta: platforms :: Lens' Meta (Set Platform)
+ Distribution.Nixpkgs.Meta: platforms :: Lens' Meta (Maybe (Set NixpkgsPlatform))
Files
- CHANGELOG.md +25/−0
- README.md +22/−0
- distribution-nixpkgs.cabal +12/−4
- src/Distribution/Nixpkgs/Meta.hs +356/−35
- src/Language/Nix/PrettyPrinting.hs +17/−9
- test/data/all-system-tuples.json +1/−0
- test/hspec.hs +112/−1
CHANGELOG.md view
@@ -1,5 +1,30 @@ # Revision history for distribution-nixpkgs +## 1.7.0++* `Distribution.Nixpkgs.Meta`+ * `pPrint (x :: Meta)` now renders every maintainer as a full attribute+ path instead of using `with`.+ * **API breaking change**: Changed types for all platform related fields /+ lenses of `Meta`, i.e. `platforms` and `hydraPlatforms`.+ * They are now wrapped in a `Maybe`. If `Nothing`, the respective attribute+ is not rendered.+ * Instead of `Platform` we now use `NixpkgsPlatform` which may also be a+ `NixpkgsPlatformGroup`, like `lib.platforms.linux`, in addition to the+ wrapped `Platform` in `NixpkgsPlatformSingle`.+ * **API breaking change**: Add new fields / lenses to `Meta`:+ * `badPlatforms`: Allows setting a list of unsupported platforms, works+ similarly to the `platform` / `hydraPlatform` lenses.+ * `mainProgram`: Allows setting the (base-)name of the main binary of a+ derivation. Not rendered if `Nothing`.+ * **API breaking change**: Remove `allKnownPlatforms`, its previous use can be+ replaced using `badPlatforms`.+ * Added `nixpkgsPlatformFromString` which parses a specific format used by+ hackage2nix's config files into either `NixpkgsPlatformSingle` or+ `NixpkgsPlatformGroup`.+* `Language.Nix.PrettyPrinting`: Added new helpers, `listattrDoc` and+ `toAscListSortedOn`.+ ## 1.6.2 * Expect `MonadFailDesugaring` (or equivalent behavior) to be the default,
README.md view
@@ -2,3 +2,25 @@ [](http://hackage.haskell.org/package/distribution-nixpkgs) [](http://stackage.org/lts/package/distribution-nixpkgs)++## Maintainer's Notes++### Keeping platform test cases up to date++As nixpkgs expands its list of supported platforms, new system tuples are added.+Therefore we need to adjust the test suite regularly in order to cover newly+added platforms. For this purpose, the test suite checks the platforms it verifies+against a list of system tuples generated from nixpkgs. This list needs to be+updated manually, so running the test suite doesn't depend on Nix being available.++To check if any new platforms need to be covered, do the following:++1. Run `./test/data/regenerate-all-system-tuples.sh /path/to/nixpkgs/checkout`.+ If no local nixpkgs is given, `<nixpkgs>` will be used.++2. Run the test suite: `cabal v2-test`.++3. If the test suite fails, add test cases for all missing system tuples.++4. In all cases, change the dates of last update in `test/hspec.hs` and+ `src/Distribution/Nixpkgs/Meta.hs` to the current day.
distribution-nixpkgs.cabal view
@@ -1,12 +1,12 @@ name: distribution-nixpkgs-version: 1.6.2+version: 1.7.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 author: Peter Simons <simons@cryp.to> maintainer: sternenseemann <sternenseemann@systemli.org>-tested-with: GHC == 8.6.5 || == 8.8.4 || == 8.10.4 || == 9.0.1+tested-with: GHC == 8.6.5 || == 8.8.4 || == 8.10.7 || == 9.0.2 || == 9.2.2 category: Distribution, Nix homepage: https://github.com/NixOS/distribution-nixpkgs bug-reports: https://github.com/NixOS/distribution-nixpkgs/issues@@ -15,6 +15,7 @@ data-files: derivation-attr-paths.nix extra-source-files: CHANGELOG.md README.md+ test/data/all-system-tuples.json source-repository head type: git@@ -38,7 +39,6 @@ , lens , pretty >= 1.1.2 , process- , split default-language: Haskell2010 other-extensions: CPP TemplateHaskell@@ -52,7 +52,15 @@ type: exitcode-stdio-1.0 main-is: hspec.hs hs-source-dirs: test- build-depends: base, deepseq, distribution-nixpkgs, hspec, lens+ build-depends: base+ , deepseq+ , distribution-nixpkgs+ , language-nix+ , hspec+ , lens+ , Cabal+ , aeson+ , directory default-language: Haskell2010 ghc-options: -Wall -Wcompat -Wincomplete-uni-patterns -Wincomplete-record-updates -Wredundant-constraints
src/Distribution/Nixpkgs/Meta.hs view
@@ -10,32 +10,218 @@ -} module Distribution.Nixpkgs.Meta- ( Meta, nullMeta- , homepage, description, license, platforms, hydraPlatforms, maintainers, broken- , allKnownPlatforms+ ( -- * Representation of the Nixpkgs Meta Set+ Meta, nullMeta+ -- ** Lenses for 'Meta'+ , homepage, description, license, platforms, badPlatforms, hydraPlatforms, mainProgram, maintainers, broken+ -- * Representation of Nixpkgs Platform Descriptions+ , NixpkgsPlatform (..)+ , nixpkgsPlatformFromString ) where -- Avoid name clash with Prelude.<> exported by post-SMP versions of base. #if MIN_VERSION_base(4,11,0) import Prelude hiding ( (<>) ) #endif+import Control.Applicative ( (<|>) ) import Control.DeepSeq-import Control.Lens+import Control.Lens hiding ( Strict )+import Data.List ( stripPrefix ) import Data.Set ( Set ) import qualified Data.Set as Set import Distribution.Nixpkgs.License+import qualified Distribution.Pretty as CabalPretty import Distribution.System import GHC.Generics ( Generic ) import Language.Nix.Identifier+import Language.Nix.Path ( path ) import Language.Nix.PrettyPrinting +-- | Representation of platform(s) as supported by nixpkgs:+--+-- * 'NixpkgsPlatformGroup' represents the name of a platform+-- list as found in @lib.platforms@. For example, at the+-- time of writing @NixpkgsPlatformGroup "darwin"@ would+-- represent the platform tuples @x86_64-darwin@, @aarch64-darwin@,+-- @i686-darwin@ and @armv7a-darwin@. Naturally, this is+-- subject to change as nixpkgs updates @lib.platforms@.+-- * 'NixpkgsPlatformSingle' indicates a single platform tuple+-- represented using Cabal's 'Platform'.+--+-- The former is useful to express related groups of+-- platforms which have similar properties. The latter+-- can be used to, for example, exclude a single, specific+-- platform.+--+-- @hackage2nix@ has used the latter approach historically+-- and is being extended to support nixpkgs' platform+-- groups as well for increased maintainer convenience.+--+-- The 'Pretty' instance allows for converting a 'NixpkgsPlatform'+-- into a Nix expression compatible with @meta.platforms@:+--+-- >>> pPrint $ NixpkgsPlatformSingle $ Platform X86_64 NetBSD+-- "x86_64-netbsd"+--+-- For 'NixpkgsPlatformGroup' we assume that the @lib@ attribute set is in+-- scope:+--+-- >>> pPrint $ NixpkgsPlatformGroup $ ident # "riscv"+-- lib.platforms.riscv+data NixpkgsPlatform+ = NixpkgsPlatformSingle Platform+ -- ^ Single platform represented as a Cabal platform. Can be understood as+ -- equivalent to Nix's system strings and will be converted to one usually.+ | NixpkgsPlatformGroup Identifier+ -- ^ 'Identifier' of the attribute name of a platform+ -- group in nixpkgs' @lib.platforms@.+ deriving (Show, Eq, Ord, Generic)++nixpkgsPlatformFromCabal :: Platform -> String+nixpkgsPlatformFromCabal (Platform arch os) = "\"" ++ nixArch ++ "-" ++ nixOs ++ "\""+ where nixArch =+ case arch of+ I386 -> "i686" -- rendered as i386 by default+ PPC -> "powerpc" -- rendered as ppc by default+ PPC64 -> "powerpc64" -- rendered as ppc64 by default+ JavaScript -> "js" -- rendered as javascript by default+ _ -> CabalPretty.prettyShow arch+ nixOs =+ case os of+ OSX -> "darwin" -- rendered as osx by default+ _ -> CabalPretty.prettyShow os++-- | Obtain a 'NixpkgsPlatform' from a string representation intended for config+-- files.+--+-- * Every string starting with @lib.platforms.@ or @platforms.@ is+-- parsed into 'NixpkgsPlatformGroup'.+-- * All other strings are attempted to be interpreted as a nix(pkgs) style+-- system tuple and parsed into 'NixpkgsPlatformSingle'.+--+-- If none of these formats match the input 'String', 'Nothing' is returned.+-- A 'Just' result thus only indicates that the format of the platform is+-- sound — 'nixpkgsPlatformFromString' does /not/ check if the parsed platform+-- actually exists.+--+-- 'NixpkgsPlatformSingle' is parsed from system tuples as understood by Nix+-- and nixpkgs. System tuples are derived from autoconf's+-- [target triplets](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.70/autoconf.html#Manual-Configuration),+-- dropping the vendor part. They have the form @cpu-os@ where @os@ can either+-- be a single component or of the form @kernel-system@ (system is an autoconf+-- term here, not a Nix system). Note that three component systems are very+-- rare. The two main candidates @x86_64-linux-musl@ and @x86_64-linux-gnu@+-- are [prohibited for historical reasons](https://github.com/NixOS/nix/blob/ec07a70979a86cc436de7e46e03789b4606d25ab/configure.ac#L26-L28)+-- and represented as plain @x86_64-linux@ instead.+--+-- Note that 'nixpkgsPlatformFromString' expects to receive a /valid/ system+-- tuple, i.e. it will accept all system tuples that have a sound format+-- (with the caveat that it will accept n-tuples for @n >= 4@ even though+-- they are technically invalid). This is done because the ambiguity of+-- system tuples requires knowledge over its legal contents in order to check+-- their validity properly. Since @lib.systems.elaborate@ from nixpkgs is the+-- source of truth in this case, we want to avoid the need to continuously+-- update @distribution-nixpkgs@ to reflect its inner workings.+--+-- 'nixpkgsPlatformFromString' does, however, some conversions to alleviate some+-- discrepancies between Cabal and nixpkgs. Parsing and rendering system tuples+-- using 'nixpkgsPlatformFromString' and rendering them via the 'Pretty'+-- instance of 'NixpkgsPlatform' should not change the system tuple+-- for tuples accepted by nixpkgs. This has been tested for all known tuples+-- (from @lib.platforms@ and @lib.systems.examples@) as of 2022-05-08.+-- Please open an issue if any newly added ones are not recognized properly.+--+-- __Warning__: 'nixpkgsPlatformFromString' consequently tries to preserve all+-- information of the passed system tuple. This means that it distinguishes+-- between things that Cabal wouldn't, e.g. `powerpc64` and `powerpc64le`. If+-- you use this function to obtain a 'Platform' that is later used to evaluate+-- a @.cabal@ file, it will behave unexpectedly in some situation. It is+-- recommended to use Cabal's own facilities or+-- @Distribution.Nixpkgs.Haskell.Platform@, provided by @cabal2nix@, instead.+--+-- 'nixpkgsPlatformFromString' is also /not/ the inverse operation for+-- 'NixpkgsPlatform'\'s 'Pretty' instance. It is not intended for parsing Nix+-- expressions.+--+-- >>> nixpkgsPlatformFromString "x86_64-netbsd"+-- Just (NixpkgsPlatformSingle (Platform X86_64 NetBSD))+-- >>> nixpkgsPlatformFromString "platforms.riscv"+-- Just (NixpkgsPlatformGroup (Identifier "riscv"))+-- >>> nixpkgsPlatformFromString "garbage"+-- Nothing+nixpkgsPlatformFromString :: String -> Maybe NixpkgsPlatform+nixpkgsPlatformFromString s = platformGroup <|> singlePlatform+ where platformGroup = do+ -- also accept "platform." as prefix to save some typing+ name <- stripPrefix "lib.platforms." s <|> stripPrefix "platforms." s+ Just $ NixpkgsPlatformGroup (ident # name)++ singlePlatform = NixpkgsPlatformSingle <$> cabalPlatformFromSystem s++-- | Parse a system tuple as understood by Nix and nixpkgs to a Cabal 'Platform'.+-- Used internally by 'nixpkgsPlatformFromString'.+--+-- >>> cabalPlatformFromSystem "x86_64-linux"+-- Just (Platform X86_64 Linux)+-- >>> cabalPlatformFromSystem "x86_64-linux-musl"+-- Just (Platform X86_64 (OtherOS "linux-musl"))+-- >>> cabalPlatformFromSystem "powerpc-darwin"+-- Just (Platform PPC OSX)+-- >>> cabalPlatformFromSystem "powerpc64le-linux"+-- Just (Platform (OtherArch "powerpc64le") Linux)+-- >>> cabalPlatformFromSystem "js-ghcjs"+-- Just (Platform JavaScript Ghcjs)+cabalPlatformFromSystem :: String -> Maybe Platform+cabalPlatformFromSystem s =+ case break (== '-') s of+ (arch, '-':os) ->+ if null arch || null os+ then Nothing+ else Just $ Platform (parseArch arch) (parseOS os)+ _ -> Nothing+ where -- Use permissive classification to also recognize autoconf / nixpkgs+ -- style OS strings, e.g. "darwin" where Cabal would expect "osx".+ --+ -- Note that we don't reimplement GHC_CONVERT_OS from GHC's configure+ -- file here at the moment. Our goal is to recognize all /well formed/+ -- nixpkgs system strings, nothing more. That this works correctly for+ -- nixpkgs systems currently in use is confirmed by the test suite.+ parseOS = classifyOS Permissive++ -- Use Strict for arch classification and add specific guards for cases+ -- where Cabal's naming expectations (which seems to be LLVM oriented)+ -- clash with what nixpkgs / autoconf use (e.g. Cabal uses "ppc" instead+ -- of "powerpc"). Using Permissive is not possible because Cabal is a bit+ -- overzealous in arch recognition: For example, it ignores endianess in+ -- the case of the POWER architectures, parsing "powerpcle" to "ppc" and+ -- "powerpc64le" to "ppc64" when they are clearly different platforms.+ --+ -- We also don't implement GHC_CONVERT_ARCH here, for the reasons stated+ -- above.+ parseArch as =+ case classifyArch Strict as of+ OtherArch "i686" -> I386+ OtherArch "js" -> JavaScript+ OtherArch "powerpc" -> PPC+ OtherArch "powerpc64" -> PPC64+ a -> a++instance Pretty NixpkgsPlatform where+ pPrint (NixpkgsPlatformSingle p) = text $ nixpkgsPlatformFromCabal p+ pPrint (NixpkgsPlatformGroup p) = pPrint+ $ path # [ ident # "lib", ident # "platforms", p ]++instance NFData NixpkgsPlatform+ -- | 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+-- (Just (Set.singleton (NixpkgsPlatformSingle (Platform X86_64 Linux))))+-- Nothing+-- (Just Set.empty)+-- (Just "example-binary") -- (Set.fromList ["joe","jane"]) -- True)) -- :}@@ -44,17 +230,43 @@ -- license = "unknown"; -- platforms = [ "x86_64-linux" ]; -- hydraPlatforms = lib.platforms.none;--- maintainers = with lib.maintainers; [ jane joe ];+-- mainProgram = "example-binary";+-- maintainers = [ lib.maintainers.jane lib.maintainers.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+ { _homepage :: String+ -- ^ URL of the package homepage+ , _description :: String+ -- ^ short description of the package+ , _license :: License+ -- ^ licensing terms+ , _platforms :: Maybe (Set NixpkgsPlatform)+ -- ^ List of platforms that are supported by the package.+ -- 'Nothing' prevents the attribute from being rendered.+ -- See 'NixpkgsPlatform' on the precise representation of platforms.+ , _badPlatforms :: Maybe (Set NixpkgsPlatform)+ -- ^ List of platforms that are known to be unsupported. This is semantically+ -- equivalent to setting the following:+ --+ -- @+ -- platforms = lib.subtractLists+ -- (initialMeta.badPlatforms or []);+ -- (initialMeta.platforms or lib.platforms.all)+ -- @+ --+ -- 'Nothing' prevents the attribute from being rendered.+ -- See 'NixpkgsPlatform' on the precise representation of platforms.+ , _hydraPlatforms :: Maybe (Set NixpkgsPlatform)+ -- ^ Platforms for which the package should be tested, built and added to the+ -- binary cache by Hydra. 'Nothing' prevents the attribute from being rendered.+ -- See 'NixpkgsPlatform' on the precise representation of platforms.+ , _mainProgram :: Maybe String+ -- ^ Filename (as in basename) of the main executable provided by the described+ -- package. @Nothing@ if it is a library or no obvious default can be chosen.+ , _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) @@ -67,39 +279,148 @@ [ 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 lib.maintainers;") (Set.map (view ident) _maintainers)+ , maybe mempty (renderPlatforms "platforms") _platforms+ , maybe mempty (renderPlatforms "badPlatforms") _badPlatforms+ , maybe mempty (renderPlatforms "hydraPlatforms") _hydraPlatforms+ , maybe mempty (attr "mainProgram" . string) _mainProgram+ , listattrDoc "maintainers" mempty $ renderMaintainers _maintainers , boolattr "broken" _broken _broken ] -renderPlatforms :: String -> Set Platform -> Doc+-- | This function renders an Nix attribute binding suitable for use in+-- an attribute set representing the given set of 'NixpkgsPlatform's.+--+-- The @field@ argument is the name of the binding, usually either+-- @platforms@, @hydraPlatforms@ or @badPlatforms@.+--+-- Platforms are rendered in the following way:+--+-- * If the given 'Set' is empty, the binding's value is @lib.platforms.none@.+-- This has been preserved for “backwards compatibility” since changing this+-- would generate a huge diff for nixpkgs' @hackage-packages.nix@ file.+--+-- * First we render all 'NixpkgsPlatformSingle' values. This is done by+-- printing a Nix list containing Nix system strings. If there are no+-- platform groups, but the 'Set' is not empty, an empty list (@[ ]@) is+-- rendered.+--+-- * Finally we render all 'NixpkgsPlatformGroup's. Since these are lists, we+-- need to append them to the (cabal) platform list via the @++@ operator.+-- For each group we render @++ lib.platforms.<group name>@.+--+-- For example:+--+-- >>> :{+-- renderPlatforms "badPlatforms"+-- $ Set.fromList [+-- NixpkgsPlatformSingle (Platform (OtherArch "armv7l") Linux),+-- NixpkgsPlatformGroup (ident # "darwin"),+-- NixpkgsPlatformGroup (ident # "windows")+-- ]+-- :}+-- badPlatforms = [+-- "armv7l-linux"+-- ] ++ lib.platforms.darwin+-- ++ lib.platforms.windows;+--+-- >>> :{+-- renderPlatforms "platforms"+-- $ Set.fromList [+-- NixpkgsPlatformGroup (ident # "x86"),+-- NixpkgsPlatformGroup (ident # "riscv"),+-- NixpkgsPlatformGroup (ident # "freebsd")+-- ]+-- :}+-- platforms =+-- lib.platforms.freebsd+-- ++ lib.platforms.riscv+-- ++ lib.platforms.x86;+--+-- >>> :{+-- renderPlatforms "platforms"+-- $ Set.fromList [+-- NixpkgsPlatformGroup (ident # "x86")+-- ]+-- :}+-- platforms = lib.platforms.x86;+--+-- >>> :{+-- renderPlatforms "platforms"+-- $ Set.fromList [+-- NixpkgsPlatformSingle (Platform I386 Linux),+-- NixpkgsPlatformSingle (Platform X86_64 Linux),+-- NixpkgsPlatformSingle (Platform AArch64 Linux),+-- NixpkgsPlatformSingle (Platform X86_64 OSX),+-- NixpkgsPlatformSingle (Platform AArch64 OSX)+-- ]+-- :}+-- platforms = [+-- "i686-linux" "x86_64-linux" "x86_64-darwin" "aarch64-linux"+-- "aarch64-darwin"+-- ];+--+-- >>> :{+-- renderPlatforms "platforms"+-- $ Set.fromList [+-- NixpkgsPlatformSingle (Platform I386 Linux),+-- NixpkgsPlatformSingle (Platform X86_64 Linux),+-- NixpkgsPlatformSingle (Platform AArch64 Linux),+-- NixpkgsPlatformSingle (Platform X86_64 OSX),+-- NixpkgsPlatformSingle (Platform AArch64 OSX),+-- NixpkgsPlatformGroup (ident # "riscv"),+-- NixpkgsPlatformGroup (ident # "arm")+-- ]+-- :}+-- platforms = [+-- "i686-linux" "x86_64-linux" "x86_64-darwin" "aarch64-linux"+-- "aarch64-darwin"+-- ] ++ lib.platforms.arm+-- ++ lib.platforms.riscv;+renderPlatforms :: String -> Set NixpkgsPlatform -> Doc renderPlatforms field ps+ -- preserve old behavior: no platforms -> lib.platforms.none | Set.null ps = sep [ text field <+> equals <+> text "lib.platforms.none" <> semi ]- | otherwise = setattr field mempty $ Set.map fromCabalPlatform ps+ | otherwise =+ sep [ text field <+> equals <+> unless (Set.null cabalPs) lbrack+ , unless (Set.null cabalPs) (nest 2 $ fsep renderedCabalPs)+ , unless (Set.null cabalPs) rbrack+ , unless (Set.null nixpkgsPs) (nest 2 renderedNixpkgsPs)+ ]+ <> semi+ where -- render nixpkgs platforms and cabal platform tuples separately+ -- since the former represents multiple platforms and meta doesn't+ -- support nested lists.+ (cabalPs, nixpkgsPs) = Set.partition isSinglePlatform ps+ isSinglePlatform (NixpkgsPlatformSingle _) = True+ isSinglePlatform _ = False + renderedCabalPs = map pPrint $ Set.toAscList cabalPs++ -- append lib.platforms list via nix's ++ at the end+ -- if there is no cabal platforms list, don't emit leading +++ appendNixpkgsP acc elem = acc $$+ if isEmpty acc && Set.null cabalPs+ then nest 3 $ pPrint elem+ else text "++" <+> pPrint elem+ renderedNixpkgsPs = Set.foldl' appendNixpkgsP mempty nixpkgsPs++ -- Helper function, roughly the inverse of nixpkgs' optionals+ unless False x = x+ unless True _ = mempty++renderMaintainers :: Set Identifier -> [Doc]+renderMaintainers = map (pPrint . toPath) . toAscListSortedOn (view ident)+ where toPath m = path # [ ident # "lib", ident # "maintainers", m]+ nullMeta :: Meta nullMeta = Meta { _homepage = error "undefined Meta.homepage" , _description = error "undefined Meta.description" , _license = error "undefined Meta.license" , _platforms = error "undefined Meta.platforms"+ , _badPlatforms = error "undefined Meta.badPlatforms" , _hydraPlatforms = error "undefined Meta.hydraPlatforms"+ , _mainProgram = error "undefined Meta.mainProgram" , _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, Platform (OtherArch "armv7l") Linux- , Platform AArch64 Linux, Platform AArch64 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 (Platform (OtherArch "armv7l") Linux) = "\"armv7l-linux\""-fromCabalPlatform (Platform AArch64 Linux) = "\"aarch64-linux\""-fromCabalPlatform (Platform AArch64 OSX) = "\"aarch64-darwin\""-fromCabalPlatform p = error ("fromCabalPlatform: invalid Nix platform" ++ show p)
src/Language/Nix/PrettyPrinting.hs view
@@ -5,8 +5,9 @@ module Language.Nix.PrettyPrinting ( onlyIf- , setattr, toAscList- , listattr+ , toAscList, toAscListSortedOn+ , setattr+ , listattr, listattrDoc , boolattr , attr , string@@ -36,18 +37,25 @@ boolattr :: String -> Bool -> Bool -> Doc boolattr n p v = if p then attr n (bool v) else empty +listattrDoc :: String -> Doc -> [Doc] -> Doc+listattrDoc n prefix vs = onlyIf (not (null vs)) $+ sep [ text n <+> equals <+> prefix <+> lbrack,+ nest 2 $ fsep vs,+ rbrack <> semi+ ]+ 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- ]+listattr n p = listattrDoc n p . map text setattr :: String -> Doc -> Set String -> Doc-setattr name prefix set = listattr name prefix (toAscList set)+setattr name prefix set = listattrDoc name prefix+ $ map text $ toAscList set +toAscListSortedOn :: (a -> String) -> Set a -> [a]+toAscListSortedOn f = sortBy (compare `on` map toLower . f) . Set.toList+ toAscList :: Set String -> [String]-toAscList = sortBy (compare `on` map toLower) . Set.toList+toAscList = toAscListSortedOn id bool :: Bool -> Doc bool True = text "true"
+ test/data/all-system-tuples.json view
@@ -0,0 +1,1 @@+["aarch64-darwin","aarch64-genode","aarch64-linux","aarch64-netbsd","aarch64-none","aarch64_be-none","arm-none","armv5tel-linux","armv6l-linux","armv6l-netbsd","armv6l-none","armv7a-darwin","armv7a-linux","armv7a-netbsd","armv7l-linux","armv7l-netbsd","avr-none","i686-cygwin","i686-darwin","i686-freebsd","i686-genode","i686-linux","i686-netbsd","i686-none","i686-openbsd","i686-windows","js-ghcjs","m68k-linux","m68k-netbsd","m68k-none","mips-linux","mips64-linux","mips64el-linux","mipsel-linux","mipsel-netbsd","mmix-mmixware","msp430-none","or1k-none","powerpc-netbsd","powerpc-none","powerpc64-linux","powerpc64le-linux","powerpcle-none","riscv32-linux","riscv32-netbsd","riscv32-none","riscv64-linux","riscv64-netbsd","riscv64-none","s390-linux","s390-none","s390x-linux","s390x-none","vc4-none","wasm32-wasi","wasm64-wasi","x86_64-cygwin","x86_64-darwin","x86_64-freebsd","x86_64-genode","x86_64-linux","x86_64-netbsd","x86_64-none","x86_64-openbsd","x86_64-redox","x86_64-solaris","x86_64-windows"]
test/hspec.hs view
@@ -3,12 +3,20 @@ import Control.DeepSeq import Control.Exception import Control.Lens+import Control.Monad (forM_)+import Data.Aeson (decodeFileStrict)+import Data.Bifunctor (second)+import Data.Maybe (fromJust) import Distribution.Nixpkgs.License import Distribution.Nixpkgs.Meta+import Distribution.System (Platform (..), OS (..), Arch (..))+import Language.Nix.Identifier+import Language.Nix.PrettyPrinting+import System.Directory (doesFileExist) import Test.Hspec main :: IO ()-main = hspec $+main = hspec $ do describe "DeepSeq instances work properly for" $ do it "License" $ mapM_ hitsBottom [Known undefined, Unknown (Just undefined)] it "Meta" $ mapM_ hitsBottom@@ -19,6 +27,109 @@ , nullMeta & maintainers .~ undefined , nullMeta & broken .~ undefined ]++ describe "Platform rendering and parsing:" $ do+ it "Checks cover all systems from all-system-tuples.json" $do+ let allSystemTuplesJson = "test/data/all-system-tuples.json"+ available <- doesFileExist allSystemTuplesJson+ if not available+ then pendingWith $ "System tuple list not found at: " ++ allSystemTuplesJson+ else do+ allSystemTuples <- decodeFileStrict allSystemTuplesJson+ map fst nixpkgsSystemMapping `shouldMatchList` fromJust allSystemTuples++ forM_ platformMapping $ \(str, plat) -> describe str $ do+ it "is rendered correctly" $ checkRendering plat str+ it "is parsed correctly" $+ nixpkgsPlatformFromString str `shouldBe` Just plat++-- All system tuples from lib.platforms as of 2022-05-08. Testing these allows+-- us to get notified about behavior change in Cabal as early as possible.+nixpkgsSystemMapping :: [(String, Platform)]+nixpkgsSystemMapping =+ [ -- lib.platforms.all+ ("aarch64-darwin", Platform AArch64 OSX)+ , ("aarch64-genode", Platform AArch64 (OtherOS "genode"))+ , ("aarch64-linux", Platform AArch64 Linux)+ , ("aarch64-netbsd", Platform AArch64 NetBSD)+ , ("aarch64-none", Platform AArch64 (OtherOS "none"))+ , ("aarch64_be-none", Platform (OtherArch "aarch64_be") (OtherOS "none"))+ , ("arm-none", Platform Arm (OtherOS "none"))+ , ("armv5tel-linux", Platform (OtherArch "armv5tel") Linux)+ , ("armv6l-linux", Platform (OtherArch "armv6l") Linux)+ , ("armv6l-netbsd", Platform (OtherArch "armv6l") NetBSD)+ , ("armv6l-none", Platform (OtherArch "armv6l") (OtherOS "none"))+ , ("armv7a-darwin", Platform (OtherArch "armv7a") OSX)+ , ("armv7a-linux", Platform (OtherArch "armv7a") Linux)+ , ("armv7a-netbsd", Platform (OtherArch "armv7a") NetBSD)+ , ("armv7l-linux", Platform (OtherArch "armv7l") Linux)+ , ("armv7l-netbsd", Platform (OtherArch "armv7l") NetBSD)+ , ("avr-none", Platform (OtherArch "avr") (OtherOS "none"))+ , ("i686-cygwin", Platform I386 (OtherOS "cygwin"))+ , ("i686-darwin", Platform I386 OSX)+ , ("i686-freebsd", Platform I386 FreeBSD)+ , ("i686-genode", Platform I386 (OtherOS "genode"))+ , ("i686-linux", Platform I386 Linux)+ , ("i686-netbsd", Platform I386 NetBSD)+ , ("i686-none", Platform I386 (OtherOS "none"))+ , ("i686-openbsd", Platform I386 OpenBSD)+ , ("i686-windows", Platform I386 Windows)+ , ("js-ghcjs", Platform JavaScript Ghcjs)+ , ("m68k-linux", Platform M68k Linux)+ , ("m68k-netbsd", Platform M68k NetBSD)+ , ("m68k-none", Platform M68k (OtherOS "none"))+ , ("mips64el-linux", Platform (OtherArch "mips64el") Linux)+ , ("mipsel-linux", Platform (OtherArch "mipsel") Linux)+ , ("mipsel-netbsd", Platform (OtherArch "mipsel") NetBSD)+ , ("mmix-mmixware", Platform (OtherArch "mmix") (OtherOS "mmixware"))+ , ("msp430-none", Platform (OtherArch "msp430") (OtherOS "none"))+ , ("or1k-none", Platform (OtherArch "or1k") (OtherOS "none"))+ , ("powerpc-netbsd", Platform PPC NetBSD)+ , ("powerpc-none", Platform PPC (OtherOS "none"))+ , ("powerpc64-linux", Platform PPC64 Linux)+ , ("powerpc64le-linux", Platform (OtherArch "powerpc64le") Linux)+ , ("powerpcle-none", Platform (OtherArch "powerpcle") (OtherOS "none"))+ , ("riscv32-linux", Platform (OtherArch "riscv32") Linux)+ , ("riscv32-netbsd", Platform (OtherArch "riscv32") NetBSD)+ , ("riscv32-none", Platform (OtherArch "riscv32") (OtherOS "none"))+ , ("riscv64-linux", Platform (OtherArch "riscv64") Linux)+ , ("riscv64-netbsd", Platform (OtherArch "riscv64") NetBSD)+ , ("riscv64-none", Platform (OtherArch "riscv64") (OtherOS "none"))+ , ("s390-linux", Platform S390 Linux)+ , ("s390-none", Platform S390 (OtherOS "none"))+ , ("s390x-linux", Platform (OtherArch "s390x") Linux)+ , ("s390x-none", Platform (OtherArch "s390x") (OtherOS "none"))+ , ("vc4-none", Platform (OtherArch "vc4") (OtherOS "none"))+ , ("wasm32-wasi", Platform (OtherArch "wasm32") (OtherOS "wasi"))+ , ("wasm64-wasi", Platform (OtherArch "wasm64") (OtherOS "wasi"))+ , ("x86_64-cygwin", Platform X86_64 (OtherOS "cygwin"))+ , ("x86_64-darwin", Platform X86_64 OSX)+ , ("x86_64-freebsd", Platform X86_64 FreeBSD)+ , ("x86_64-genode", Platform X86_64 (OtherOS "genode"))+ , ("x86_64-linux", Platform X86_64 Linux)+ , ("x86_64-netbsd", Platform X86_64 NetBSD)+ , ("x86_64-none", Platform X86_64 (OtherOS "none"))+ , ("x86_64-openbsd", Platform X86_64 OpenBSD)+ , ("x86_64-redox", Platform X86_64 (OtherOS "redox"))+ , ("x86_64-solaris", Platform X86_64 Solaris)+ , ("x86_64-windows", Platform X86_64 Windows)+ -- lib.systems.examples+ , ("mips-linux", Platform Mips Linux)+ , ("mips64-linux", Platform (OtherArch "mips64") Linux)+ ]++platformMapping :: [(String, NixpkgsPlatform)]+platformMapping = map (second NixpkgsPlatformSingle) nixpkgsSystemMapping+ ++ map platformGroupMapping [ "riscv", "x86", "linux", "darwin" ]++platformGroupMapping :: String -> (String, NixpkgsPlatform)+platformGroupMapping name =+ ("lib.platforms." ++ name, NixpkgsPlatformGroup (ident # name))++checkRendering :: NixpkgsPlatform -> String -> Expectation+checkRendering plat@(NixpkgsPlatformSingle _) str =+ prettyShow plat `shouldBe` "\"" ++ str ++ "\""+checkRendering plat str = prettyShow plat `shouldBe` str hitsBottom :: NFData a => a -> Expectation hitsBottom x = evaluate (rnf x) `shouldThrow` anyErrorCall