packages feed

arch-hs 0.12.2 → 0.12.3

raw patch · 8 files changed

+140/−29 lines, 8 filesdep ~Cabaldep ~template-haskellPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: Cabal, template-haskell

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -3,6 +3,16 @@ `arch-hs` uses [PVP Versioning][1]. The changelog is available [on GitHub][2]. +## 0.12.3++- Teach `arch-hs-rdepcheck` to validate a candidate version against reverse dependency ranges++- Use the newest cached Hackage index when multiple mirrors are available++- Update supported GHC/Cabal dependency bounds++- Update name preset+ ## 0.12.2  - Fail `arch-hs-sync submit` when Hackage returns an unsuccessful upload status
README.md view
@@ -511,7 +511,29 @@ ✔ Success! ``` -`arch-hs-diff` does not require hackage db, it downloads cabal files from hackage server instead. +`arch-hs-diff` does not require hackage db, it downloads cabal files from hackage server instead.++## Reverse dependency checks++`arch-hs-rdepcheck` lists Haskell reverse dependencies in [extra] and the Cabal version ranges they require:++```+$ arch-hs-rdepcheck aeson+Reverse dependency: agda+  Depends: >=1.1.2.0 && <2.3+...+```++Pass an optional version to check whether that version satisfies every listed range. Out-of-range entries are printed as errors, and the command exits with a non-zero status if any range fails:++```+$ arch-hs-rdepcheck aeson 3.0+Reverse dependency: agda+  Depends: >=1.1.2.0 && <2.3+  Error: 3.0 is outside Depends range (>=1.1.2.0 && <2.3)+...+68 reverse dependency range check(s) failed.+```  ## Sync 
arch-hs.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               arch-hs-version:            0.12.2+version:            0.12.3 synopsis:           Distribute hackage packages to archlinux description:   @arch-hs@ is a command-line program, which simplifies the process of producing@@ -23,7 +23,7 @@   CHANGELOG.md   README.md -tested-with:        GHC ==8.10.7 || ==9.0.2 || ==9.2.3+tested-with:        GHC ==9.2.8 || ==9.4.8 || ==9.6.7 || ==9.8.4  source-repository head   type:     git@@ -41,7 +41,7 @@     , arch-web                     ^>=0.3.2     , base                         >=4.12     && <5     , bytestring-    , Cabal                        >=3.2      && <3.11+    , Cabal                        >=3.8      && <3.11     , conduit                      ^>=1.3.2     , conduit-extra                ^>=1.3.5     , containers@@ -64,7 +64,7 @@     , servant-client               >=0.18.2   && <0.21     , split                        ^>=0.2.3     , tar-conduit                  ^>=0.3.2   || ^>=0.4.0-    , template-haskell             ^>=2.16.0  || ^>=2.17.0 || ^>=2.18.0 || ^>=2.19.0 || ^>=2.20.0 || ^>=2.21.0+    , template-haskell             ^>=2.18.0  || ^>=2.19.0 || ^>=2.20.0 || ^>=2.21.0     , text    ghc-options:
data/NAME_PRESET.json view
@@ -8,6 +8,7 @@   "c2hs": "c2hs",   "haskell-cabal": "Cabal",   "cabal-install": "cabal-install",+  "cabal-fmt": "cabal-fmt",   "cabal-plan": "cabal-plan",   "haskell-cabal-syntax": "Cabal-syntax",   "cbor-tool": "cbor-tool",@@ -15,6 +16,7 @@   "clash-ghc": "clash-ghc",   "cryptol": "cryptol",   "darcs": "darcs",+  "dice": "dice",   "dhall": "dhall",   "dhall-bash": "dhall-bash",   "dhall-docs": "dhall-docs",@@ -26,16 +28,15 @@   "gitit": "gitit",   "glirc": "glirc",   "happy": "happy",+  "haskell-bindings-dsl": "bindings-DSL",   "haskell-boolean": "Boolean",   "haskell-boundedchan": "BoundedChan",   "haskell-chasingbottoms": "ChasingBottoms",   "haskell-ci": "haskell-ci",-  "haskell-configfile": "ConfigFile",   "haskell-cracknum": "crackNum",   "haskell-dav": "DAV",   "haskell-decimal": "Decimal",   "haskell-diff": "Diff",-  "haskell-drbg": "DRBG",   "haskell-edisonapi": "EdisonAPI",   "haskell-edisoncore": "EdisonCore",   "haskell-findbin": "FindBin",@@ -113,11 +114,11 @@   "stylish-haskell": "stylish-haskell",   "taffybar": "taffybar",   "tamarin-prover": "tamarin-prover",-  "tidalcycles": "tidal",   "unlambda": "unlambda",   "uusi": "uusi",   "xmobar": "xmobar",   "xmonad": "xmonad",+  "xmonad-dbus": "xmonad-dbus",   "xmonad-contrib": "xmonad-contrib",   "xmonad-extras": "xmonad-extras",   "xmonad-utils": "xmonad-utils"
rdepcheck/Args.hs view
@@ -14,7 +14,8 @@   { optFlags :: FlagAssignments,     optExtraDB :: ExtraDBOptions,     optHackage :: HackageDBOptions,-    optPackageName :: PackageName+    optPackageName :: PackageName,+    optCheckVersion :: Maybe Version   }  cmdOptions :: Parser Options@@ -24,14 +25,15 @@     <*> extraDBOptionsParser     <*> hackageDBOptionsParser     <*> argument optPackageNameReader (metavar "TARGET")+    <*> optional (argument optVersionReader (metavar "VERSION"))  runArgsParser :: IO Options runArgsParser = do   (x, ()) <-     simpleOptions       archHsVersion-      "arch-hs-rdepcheck - check the version of a dependent Haskell package"-      "arch-hs-rdepcheck is a CLI tool that shows all reverse dependencies of a Haskell package in [extra], giving the version range how it is depended on"+      "arch-hs-rdepcheck - inspect reverse dependency version ranges"+      "arch-hs-rdepcheck shows all reverse dependencies of a Haskell package in [extra] and the version ranges they require. If VERSION is provided, it reports ranges that do not accept VERSION and exits with failure."       cmdOptions       empty   pure x
rdepcheck/Check.hs view
@@ -6,7 +6,7 @@  module Check (check) where -import Control.Monad (forM_, unless)+import Control.Monad (forM, unless) import Data.List (find) import qualified Data.Map.Strict as Map import Data.Maybe (catMaybes)@@ -41,9 +41,10 @@       Embed IO     ]     r =>+  Maybe Version ->   PackageName ->-  Sem r ()-check target = do+  Sem r Int+check mVersion target = do   let aTarget = toArchLinuxName target   exists <- isInExtra aTarget   unless exists $ throw $ PkgNotFound target@@ -65,7 +66,7 @@       )       . Map.toList       <$> ask @ExtraDB-  forM_ reverseDeps $ \(PkgDesc {..}, src) -> do+  failures <- forM reverseDeps $ \(PkgDesc {..}, src) -> do     eCabal <-       try @MyException $         getCabal (toHackageName _name) =<< case simpleParsec _version of@@ -74,15 +75,46 @@     case eCabal of       Right cabal -> do         result <- getDepVersion cabal target src+        let failedRanges = versionFailures mVersion result         embed . putDoc $           vsep             ( annMagneta "Reverse dependency" <> colon                 <+> pretty (unArchLinuxName _name)-                : [indent 2 $ pretty s <> colon <+> viaPretty r | (s, r) <- result]+                : (rangeDocs result <> versionErrors mVersion failedRanges)             )             <> line-      Left e ->+        pure $ length failedRanges+      Left e -> do         printWarn $ "Skip" <+> pretty (unArchLinuxName _name) <> colon <+> viaShow e+        pure 0+  pure $ sum failures++rangeDocs :: [(DepSrc, VersionRange)] -> [Doc AnsiStyle]+rangeDocs result =+  [ indent 2 $ pretty s <> colon <+> viaPretty r+    | (s, r) <- result+  ]++versionFailures :: Maybe Version -> [(DepSrc, VersionRange)] -> [(DepSrc, VersionRange)]+versionFailures Nothing _ = []+versionFailures (Just version) result =+  [ (src, range)+    | (src, range) <- result,+      not $ withinRange version range+  ]++versionErrors :: Maybe Version -> [(DepSrc, VersionRange)] -> [Doc AnsiStyle]+versionErrors Nothing _ = []+versionErrors (Just version) result =+  [ indent 2 $+      annRed "Error:"+        <+> viaPretty version+        <+> "is outside"+        <+> pretty src+        <+> "range"+        <+> parens (viaPretty range)+    | (src, range) <- result+  ]  getDepVersion ::   Members
rdepcheck/Main.hs view
@@ -16,6 +16,7 @@ import Distribution.ArchHs.Types import GHC.IO.Encoding (setLocaleEncoding) import GHC.IO.Encoding.UTF8 (utf8)+import System.Exit (exitFailure)  main :: IO () main = printHandledIOException $@@ -32,7 +33,19 @@     extra <- loadExtraDBFromOptions optExtraDB      printInfo "Start running..."-    runCheck hackage extra optFlags (subsumeGHCVersion $ check optPackageName) & printAppResult+    runCheck hackage extra optFlags (subsumeGHCVersion $ check optCheckVersion optPackageName) & printRdepcheckResult++printRdepcheckResult :: IO (Either MyException Int) -> IO ()+printRdepcheckResult io = do+  result <- io+  case result of+    Left x -> do+      printError $ "Runtime Exception" <> colon <+> viaShow x+      exitFailure+    Right 0 -> printSuccess "Success!"+    Right n -> do+      printError $ pretty n <+> "reverse dependency range check(s) failed."+      exitFailure  runCheck ::   HackageDB ->
src/Distribution/ArchHs/Hackage.hs view
@@ -20,29 +20,60 @@   ) where +import Control.Monad (filterM) import qualified Data.ByteString as BS+import Data.List (maximumBy) import qualified Data.Map as Map-import Data.Maybe (fromJust)+import Data.Maybe (catMaybes, fromJust)+import Data.Ord (comparing) import Distribution.ArchHs.Exception import Distribution.ArchHs.Internal.Prelude import Distribution.ArchHs.Types import Distribution.ArchHs.Utils (getPkgName, getPkgVersion) import Distribution.Hackage.DB (HackageDB, VersionData (VersionData, cabalFile), readTarball, tarballHashes)+import Distribution.Hackage.DB.Path (cabalStateDir) import Distribution.PackageDescription.Parsec (parseGenericPackageDescriptionMaybe)-import System.Directory (findFile, getHomeDirectory, listDirectory)+import System.Directory (doesDirectoryExist, doesFileExist, getModificationTime, listDirectory) --- | Look up hackage tarball path from @~/.cabal@.--- Arbitrary hackage mirror is potential to be selected.--- Preferred to @01-index.tar@, whereas fallback to @00-index.tar@.+-- | Look up hackage tarball path from Cabal's package index cache.+-- Preferred to the newest @01-index.tar@, whereas fallback to the newest @00-index.tar@. lookupHackagePath :: IO FilePath lookupHackagePath = do-  home <- (\d -> d </> ".cabal" </> "packages") <$> getHomeDirectory-  subs <- fmap (home </>) <$> listDirectory home-  legacy <- findFile subs "00-index.tar"-  new <- findFile subs "01-index.tar"-  case new <|> legacy of+  root <- (</> "packages") <$> cabalStateDir+  candidates <- hackageIndexCandidates root+  case newestIndex "01-index.tar" candidates <|> newestIndex "00-index.tar" candidates of     Just x -> return x-    Nothing -> fail $ "Unable to find hackage index tarball from " <> show subs+    Nothing -> fail $ "Unable to find hackage index tarball from " <> root+  where+    hackageIndexCandidates root = do+      exists <- doesDirectoryExist root+      if exists+        then do+          rootIndexes <- indexesIn root+          dirs <- fmap (root </>) <$> listDirectory root+          repoDirs <- filterM doesDirectoryExist dirs+          repoIndexes <- concat <$> traverse indexesIn repoDirs+          pure $ rootIndexes <> repoIndexes+        else pure []++    indexesIn dir =+      catMaybes+        <$> traverse+          ( \name -> do+              let path = dir </> name+              exists <- doesFileExist path+              if exists+                then do+                  time <- getModificationTime path+                  pure $ Just (name, path, time)+                else pure Nothing+          )+          ["01-index.tar", "00-index.tar"]++    newestIndex name candidates =+      case filter (\(candidateName, _, _) -> candidateName == name) candidates of+        [] -> Nothing+        xs -> Just $ (\(_, path, _) -> path) (maximumBy (comparing (\(_, _, time) -> time)) xs)  -- | Read and parse hackage index tarball. loadHackageDB :: FilePath -> IO HackageDB