Skip to content

Minimal migration to Cabal-3.6.3.0 #1038

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Mar 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jobs:
fail-fast: false
matrix:
versions:
- ghc: '9.2.2'
cabal: '3.6'
- ghc: '9.0.2'
cabal: '3.6'
- ghc: '8.10.7'
Expand Down
18 changes: 9 additions & 9 deletions hackage-server.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ copyright: 2008-2015 Duncan Coutts,
license: BSD-3-Clause
license-file: LICENSE

tested-with: GHC == { 8.10.7, 8.8.4 }
tested-with: GHC == { 9.2.2, 9.0.2, 8.10.7, 8.8.4 }

data-dir: datafiles
data-files:
Expand Down Expand Up @@ -95,25 +95,25 @@ common defaults
-- see `cabal.project.local-ghc-${VERSION}` files
build-depends:
, array >= 0.5 && < 0.6
, base >= 4.13 && < 4.16
, base >= 4.13 && < 4.17
, binary >= 0.8 && < 0.9
, bytestring >= 0.10 && < 0.11
, bytestring >= 0.10 && < 0.12
, containers ^>= 0.6.0
, deepseq >= 1.4 && < 1.5
, directory >= 1.3 && < 1.4
, filepath >= 1.4 && < 1.5
, mtl ^>= 2.2.1
, pretty >= 1.1 && < 1.2
, process >= 1.6 && < 1.7
, text ^>= 1.2.2
, time >= 1.9 && < 1.12
, text ^>= 1.2.5.0
, time >= 1.9 && < 1.13
, transformers >= 0.5 && < 0.6
, unix >= 2.7 && < 2.8
, scientific
-- other dependencies shared by most components
build-depends:
, aeson ^>= 2.0.3.0
, Cabal ^>= 3.4.1.0
, Cabal ^>= 3.6.3.0
, fail ^>= 4.9.0
-- we use Control.Monad.Except, introduced in mtl-2.2.1
, network >= 3 && < 3.2
Expand Down Expand Up @@ -356,15 +356,15 @@ library lib-server
-- NB: see also build-depends in `common defaults`!
build-depends:
, HStringTemplate ^>= 0.8
, HTTP ^>= 4000.3.6
, HTTP ^>= 4000.3.16
, QuickCheck ^>= 2.14
, acid-state ^>= 0.16
, async ^>= 2.2.1
-- requires bumping http-io-streams
, attoparsec ^>= 0.14.4
, base16-bytestring ^>= 1.0
-- requires bumping http-io-streams
, base64-bytestring ^>= 1.1
, base64-bytestring ^>= 1.2.1.0
--NOTE: blaze-builder-0.4 is now a compat package that uses bytestring-0.10 builder
, blaze-builder ^>= 0.4
, blaze-html ^>= 0.9
Expand Down Expand Up @@ -511,7 +511,7 @@ test-suite HighLevelTest
-- component-specific dependencies
, xml ^>= 1.3.14
, io-streams ^>= 1.5.0.1
, http-io-streams ^>= 0.1.0.0
, http-io-streams ^>= 0.1.6.1

test-suite CreateUserTest
import: test-defaults
Expand Down
14 changes: 12 additions & 2 deletions src/Distribution/Server/Packages/Render.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,15 @@ import Distribution.PackageDescription.Configuration
import Distribution.Package
import Distribution.Text
import Distribution.Pretty (prettyShow)
import Distribution.Version
import Distribution.Version (noVersion)
import Distribution.Types.VersionInterval.Legacy
-- Andreas Abel, 2022-03-27:
-- Note that this "Legacy" module is both new and deprecated in Cabal-3.6.
-- However, the non-deprecated module "Distribution.Types.VersionInterval"
-- does not define the functions anymore we rely on here, namely
-- @{union,intersect}VersionIntervals@.
-- I criticized this unfortunate development at length at:
-- https://github.com/haskell/cabal/issues/7916
import Distribution.ModuleName as ModuleName
import Distribution.Types.ModuleReexport

Expand All @@ -41,7 +49,9 @@ import Distribution.Server.Packages.Types
import Distribution.Server.Packages.ModuleForest
import qualified Distribution.Server.Users.Users as Users
import Distribution.Server.Users.Types
import Distribution.Utils.Path (getSymbolicPath)
import Distribution.Utils.ShortText (fromShortText)

import qualified Data.TarIndex as TarIndex
import Data.TarIndex (TarIndex, TarEntryOffset)

Expand Down Expand Up @@ -95,7 +105,7 @@ doPackageRender users info = PackageRender
, rendSublibraryDeps = (unUnqualComponentName *** depTree libBuildInfo)
`map` condSubLibraries genDesc
, rendLicenseName = prettyShow (license desc) -- maybe make this a bit more human-readable
, rendLicenseFiles = licenseFiles desc
, rendLicenseFiles = map getSymbolicPath $ licenseFiles desc
, rendMaintainer = case fromShortText $ maintainer desc of
"None" -> Nothing
"none" -> Nothing
Expand Down
4 changes: 2 additions & 2 deletions src/Distribution/Server/Util/ParseSpecVer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -239,8 +239,8 @@ decodeVerFallback v0 = simpleParse v <|> parseSpecVR
parseSpecVR = do
vr <- simpleParse v
case asVersionIntervals vr of
[] -> Just $ mkVersion [0]
((LowerBound version _, _):_) -> Just $ version
VersionInterval (LowerBound version _) _ : _ -> Just version
[] -> Just $ mkVersion [0]

v = BC8.unpack v0

Expand Down
84 changes: 72 additions & 12 deletions tests/PackageTestMain.hs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
-- | Test that Hackage accepts or refuses certain packages.

module Main
( main
) where
Expand All @@ -14,15 +16,19 @@ import Distribution.Server.Packages.Unpack
import Distribution.Server.Packages.UnpackTest

import Test.Tasty (defaultMain, TestTree, testGroup)
import Test.Tasty.HUnit (testCase, Assertion)
import Test.Tasty.HUnit (testCase, Assertion, HasCallStack)

main :: IO ()
main = defaultMain allTests

allTests :: TestTree
allTests = testGroup "PackageTests"
[ testGroup "Tar file permissions" tarPermissions
, testGroup "Cabal package integrity tests" cabalPackageCheckTests]
, testGroup "Cabal package integrity tests" cabalPackageCheckTests
]

---------------------------------------------------------------------------
-- * File permission tests

tarPermissions :: [TestTree]
tarPermissions =
Expand All @@ -34,7 +40,8 @@ tarPermissions =
(testPermissions "tests/permissions-tarballs/bad-file-perms.tar.gz" badFileMangler)
, testCase
"Bad Dir Permissions"
(testPermissions "tests/permissions-tarballs/bad-dir-perms.tar.gz" badDirMangler)]
(testPermissions "tests/permissions-tarballs/bad-dir-perms.tar.gz" badDirMangler)
]

goodMangler :: (Tar.Entry -> Maybe CombinedTarErrs)
goodMangler = const Nothing
Expand All @@ -51,45 +58,98 @@ badDirMangler entry =
Tar.Directory -> Just $ PermissionsError (Tar.entryPath entry) 0o700
_ -> Nothing

---------------------------------------------------------------------------
-- * Package integry tests

cabalPackageCheckTests :: [TestTree]
cabalPackageCheckTests =
-- Failing tests
[ testCase "Missing ./configure script" missingConfigureScriptTest
, testCase "Missing directories in tar file" missingDirsInTarFileTest
, testCase "Bad spec-version" badSpecVer
-- Successful tests
, testCase "Missing directories in tar file" missingDirsInTarFileTest
, testCase "Accept GHC 9.2 LANGUAGE extensions" acceptGHC902LanguageExtensions
]

---------------------------------------------------------------------------
-- ** Tests that must fail

-- | If @build-type: Configure@, then there must be a @./configure@ script.

missingConfigureScriptTest :: Assertion
missingConfigureScriptTest =
do tar <- tarGzFile "missing-configure-0.1.0.0"
now <- getCurrentTime
case unpackPackage now "missing-configure-0.1.0.0.tar.gz" tar of
Right _ -> HUnit.assertFailure "expected error"
Right _ -> HUnit.assertFailure "error: unexpected success"
Left err ->
HUnit.assertBool
("Error found, but not about missing ./configure: " ++ err)
("The 'build-type' is 'Configure'" `isInfixOf` err)

-- | The @cabal-version@ must be valid.

badSpecVer :: Assertion
badSpecVer =
do tar <- tarGzFile "bad-specver-package-0"
now <- getCurrentTime
case unpackPackage now "bad-specver-package-0.tar.gz" tar of
Right _ -> HUnit.assertFailure "expected error"
Right _ -> HUnit.assertFailure "error: unexpected success"
Left err ->
HUnit.assertBool
("Error found, but not about invalid spec version: " ++ err)
("cabal spec version" `isInfixOf` err)

---------------------------------------------------------------------------
-- ** Tests that must succeed

-- | Some tar files in hackage are missing directory entries.
-- Ensure that they can be verified even without the directory entries.

missingDirsInTarFileTest :: Assertion
missingDirsInTarFileTest =
do tar <- fmap keepOnlyFiles (tarGzFile "correct-package-0.1.0.0")
now <- getCurrentTime
case unpackPackage now "correct-package-0.1.0.0.tar.gz" tar of
Right _ -> return ()
Left err ->
HUnit.assertFailure ("Excpected success but got: " ++ show err)
successTestTGZ pkg =<< do keepOnlyFiles <$> tarGzFile pkg
where
pkg = "correct-package-0.1.0.0"

-- | Hackage should accept GHC 9.2 language extensions (issue #1030).

acceptGHC902LanguageExtensions :: Assertion
acceptGHC902LanguageExtensions = successTest "LANGUAGE-GHC-9.2"

---------------------------------------------------------------------------
-- * Auxiliary functions to construct tests

-- | A generic successful test, given a directory with the package contents.
--
-- Note: the 'HasCallStack' constraint ensures that the assertion failure
-- is thrown at the invocation site of this function.
--
successTest
:: HasCallStack
=> String -- ^ The directory which is also the package name.
-> Assertion
successTest pkg = successTestTGZ pkg =<< tarGzFile pkg

-- | A successful test, given the package name and its @.tgz@ stream.
--
-- Note: the 'HasCallStack' constraint ensures that the assertion failure
-- is thrown at the invocation site of this function.
--
successTestTGZ
:: HasCallStack
=> String -- ^ The package name which is also the stem of the @.tgz@ file.
-> ByteString -- ^ The content of the @.tgz@ archive.
-> Assertion
successTestTGZ pkg tar = do
now <- getCurrentTime
case unpackPackage now (pkg ++ ".tar.gz") tar of
Right _ -> return ()
Left err ->
HUnit.assertFailure $ "Expected success, but got: " ++ show err

---------------------------------------------------------------------------
-- * Tar utilities

tarGzFile :: String -> IO ByteString
tarGzFile name = do
Expand Down
20 changes: 20 additions & 0 deletions tests/unpack-checks/LANGUAGE-GHC-9.2/LANGUAGE-GHC.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: LANGUAGE-GHC
version: 9.2
synopsis: Test for LANGUAGE extensions (issue #1030)
description: Test whether Hackage accepts the latest LANGUAGE extensions
license: BSD3
license-file: LICENSE
author: Hackage Server Team
maintainer: no@email.com
category: Test case
build-type: Simple
cabal-version: >=1.10

executable foo
main-is: Main.hs
build-depends: base >=4.16 && <4.17
default-language: GHC2021
default-extensions:
-- These LANGUAGE extensions are new in GHC 9.2:
NoFieldSelectors
OverloadedRecordDot
30 changes: 30 additions & 0 deletions tests/unpack-checks/LANGUAGE-GHC-9.2/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
Copyright (c) 2016, Hackage Server Team

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 Hackage Server Team 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.
4 changes: 4 additions & 0 deletions tests/unpack-checks/LANGUAGE-GHC-9.2/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Main where

main :: IO ()
main = putStrLn "Hello, Haskell!"
2 changes: 2 additions & 0 deletions tests/unpack-checks/LANGUAGE-GHC-9.2/Setup.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain