diff --git a/.docker/validate-8.0.2.dockerfile b/.docker/validate-8.0.2.dockerfile deleted file mode 100644 index aab9315c692..00000000000 --- a/.docker/validate-8.0.2.dockerfile +++ /dev/null @@ -1,69 +0,0 @@ -FROM phadej/ghc:8.0.2-bionic - -# Install cabal-plan -RUN mkdir -p /root/.cabal/bin && \ - curl -L https://github.com/haskell-hvr/cabal-plan/releases/download/v0.6.2.0/cabal-plan-0.6.2.0-x86_64-linux.xz > cabal-plan.xz && \ - echo "de73600b1836d3f55e32d80385acc055fd97f60eaa0ab68a755302685f5d81bc cabal-plan.xz" | sha256sum -c - && \ - xz -d < cabal-plan.xz > /root/.cabal/bin/cabal-plan && \ - rm -f cabal-plan.xz && \ - chmod a+x /root/.cabal/bin/cabal-plan - - -# Update index -RUN cabal v2-update --index-state="2020-06-12T23:36:15Z" - -# We install happy, so it's in the store; we (hopefully) don't use it directly. -RUN cabal v2-install happy --constraint 'happy ^>=1.19.12' - -# Install some other dependencies -# Remove $HOME/.ghc so there aren't any environments -RUN cabal v2-install -w ghc-8.0.2 --lib \ - Cabal \ - aeson \ - async \ - base-compat \ - base16-bytestring \ - base64-bytestring \ - cryptohash-sha256 \ - Diff \ - echo \ - ed25519 \ - edit-distance \ - HTTP \ - lukko \ - network \ - optparse-applicative \ - pretty-show \ - regex-compat-tdfa \ - regex-posix \ - regex-tdfa \ - rere \ - statistics \ - tar \ - tasty \ - tasty-golden \ - tasty-hunit \ - tasty-quickcheck \ - tree-diff \ - void \ - zlib \ - resolv \ - --constraint="rere -rere-cfg" \ - --constraint="these -assoc" \ - --constraint="bytestring installed" \ - --constraint="binary installed" \ - --constraint="containers installed" \ - --constraint="deepseq installed" \ - --constraint="directory installed" \ - --constraint="filepath installed" \ - --constraint="pretty installed" \ - --constraint="process installed" \ - --constraint="time installed" \ - --constraint="unix installed" \ - --constraint="transformers installed" \ - && rm -rf $HOME/.ghc - -# Validate -WORKDIR /build -COPY . /build -RUN sh ./validate.sh -w ghc-8.0.2 -v diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index e47727ec695..3401a20a920 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -38,7 +38,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest", "macos-latest", "windows-latest"] - ghc: ["9.2.3", "9.0.2", "8.10.7", "8.8.4", "8.6.5", "8.4.4", "8.0.2"] + ghc: ["9.2.3", "9.0.2", "8.10.7", "8.8.4", "8.6.5", "8.4.4"] exclude: # lot of segfaults caused by ghc bugs - os: "windows-latest" @@ -49,16 +49,6 @@ jobs: # it often randomly does "C:\Users\RUNNER~1\AppData\Local\Temp\ghcFEDE.c: DeleteFile "\\\\?\\C:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\ghcFEDE.c": permission denied (Access is denied.)" - os: "windows-latest" ghc: "8.6.5" - include: - - os: "ubuntu-latest" - ghc: "8.0.2" - cli: "false" - - os: "macos-latest" - ghc: "8.0.2" - cli: "false" - - os: "windows-latest" - ghc: "8.0.2" - cli: "false" steps: diff --git a/Cabal-syntax/src/Distribution/Types/ComponentName.hs b/Cabal-syntax/src/Distribution/Types/ComponentName.hs index 9b5373b4ddb..0dc0b3137c2 100644 --- a/Cabal-syntax/src/Distribution/Types/ComponentName.hs +++ b/Cabal-syntax/src/Distribution/Types/ComponentName.hs @@ -1,9 +1,11 @@ {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE PatternSynonyms #-} module Distribution.Types.ComponentName ( - ComponentName(..), + ComponentName(.., CFLibName, CExeName, CTestName, CBenchName), showComponentName, + componentNameRaw, componentNameStanza, componentNameString, ) where @@ -21,12 +23,32 @@ import qualified Distribution.Compat.CharParsing as P -- Libraries live in a separate namespace, so must distinguish data ComponentName = CLibName LibraryName - | CFLibName UnqualComponentName - | CExeName UnqualComponentName - | CTestName UnqualComponentName - | CBenchName UnqualComponentName + | CNotLibName NotLibComponentName deriving (Eq, Generic, Ord, Read, Show, Typeable) +data NotLibComponentName + = CNLFLibName { toCompName :: UnqualComponentName } + | CNLExeName { toCompName :: UnqualComponentName } + | CNLTestName { toCompName :: UnqualComponentName } + | CNLBenchName { toCompName :: UnqualComponentName } + deriving (Eq, Generic, Ord, Read, Show, Typeable) + +pattern CFLibName :: UnqualComponentName -> ComponentName +pattern CFLibName n = CNotLibName (CNLFLibName n) + +pattern CExeName :: UnqualComponentName -> ComponentName +pattern CExeName n = CNotLibName (CNLExeName n) + +pattern CTestName :: UnqualComponentName -> ComponentName +pattern CTestName n = CNotLibName (CNLTestName n) + +pattern CBenchName :: UnqualComponentName -> ComponentName +pattern CBenchName n = CNotLibName (CNLBenchName n) +{-# COMPLETE CLibName, CFLibName, CExeName, CTestName, CBenchName #-} + +instance Binary NotLibComponentName +instance Structured NotLibComponentName + instance Binary ComponentName instance Structured ComponentName @@ -59,6 +81,10 @@ showComponentName (CExeName name) = "executable '" ++ prettyShow name ++ "'" showComponentName (CTestName name) = "test suite '" ++ prettyShow name ++ "'" showComponentName (CBenchName name) = "benchmark '" ++ prettyShow name ++ "'" +componentNameRaw :: ComponentName -> String +componentNameRaw l@(CLibName _) = showComponentName l +componentNameRaw (CNotLibName x) = prettyShow $ toCompName x + componentNameStanza :: ComponentName -> String componentNameStanza (CLibName lib) = libraryNameStanza lib componentNameStanza (CFLibName name) = "foreign-library " ++ prettyShow name @@ -71,8 +97,5 @@ componentNameStanza (CBenchName name) = "benchmark " ++ prettyShow name -- @Nothing@ if the 'ComponentName' was for the public -- library. componentNameString :: ComponentName -> Maybe UnqualComponentName -componentNameString (CLibName lib) = libraryNameString lib -componentNameString (CFLibName n) = Just n -componentNameString (CExeName n) = Just n -componentNameString (CTestName n) = Just n -componentNameString (CBenchName n) = Just n +componentNameString (CLibName lib) = libraryNameString lib +componentNameString (CNotLibName x) = Just $ toCompName x diff --git a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs index 56be131a9f1..bbf5481da55 100644 --- a/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs +++ b/Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs @@ -29,7 +29,7 @@ tests = testGroup "Distribution.Utils.Structured" , testCase "GenericPackageDescription" $ md5Check (Proxy :: Proxy GenericPackageDescription) 0xaf3d4c667a8f019c98a45451419ad71c , testCase "LocalBuildInfo" $ - md5Check (Proxy :: Proxy LocalBuildInfo) 0x6d132d3f99c869b678468256f24b6241 + md5Check (Proxy :: Proxy LocalBuildInfo) 0x8ef5a39cb640e4340cf5c43a8300ff94 #endif ] diff --git a/Makefile b/Makefile index 831e4aa5e4b..39ca47756ca 100644 --- a/Makefile +++ b/Makefile @@ -126,7 +126,6 @@ cabal-install-test-accept: # # make validate-via-docker-all -j4 -O # -validate-via-docker-all : validate-via-docker-8.0.2 validate-via-docker-all : validate-via-docker-8.2.2 validate-via-docker-all : validate-via-docker-8.4.4 validate-via-docker-all : validate-via-docker-8.6.5 @@ -147,9 +146,6 @@ validate-dockerfiles : .docker/validate-8.6.5.dockerfile # and we have a test relying on this limit being sufficiently small DOCKERARGS:=--ulimit nofile=1024:1024 -validate-via-docker-8.0.2: - docker build $(DOCKERARGS) -t cabal-validate:8.0.2 -f .docker/validate-8.0.2.dockerfile . - validate-via-docker-8.2.2: docker build $(DOCKERARGS) -t cabal-validate:8.2.2 -f .docker/validate-8.2.2.dockerfile . diff --git a/cabal-dev-scripts/src/GenValidateDockerfile.hs b/cabal-dev-scripts/src/GenValidateDockerfile.hs index c5a5c0c7cd7..10041b7cc5c 100644 --- a/cabal-dev-scripts/src/GenValidateDockerfile.hs +++ b/cabal-dev-scripts/src/GenValidateDockerfile.hs @@ -45,7 +45,6 @@ params = Map.fromList , pair "8.6.5" $ Z "ghc-8.6.5" "8.6.5-bionic" False True False True "" , pair "8.4.4" $ Z "ghc-8.4.4" "8.4.4-bionic" False True False True "" , pair "8.2.2" $ Z "ghc-8.2.2" "8.2.2-bionic" True True False True "" - , pair "8.0.2" $ Z "ghc-8.0.2" "8.0.2-bionic" True True False True "" ] where pair = (,) diff --git a/cabal-install/src/Distribution/Client/CmdErrorMessages.hs b/cabal-install/src/Distribution/Client/CmdErrorMessages.hs index ed80c474e8c..cf41fc4ebac 100644 --- a/cabal-install/src/Distribution/Client/CmdErrorMessages.hs +++ b/cabal-install/src/Distribution/Client/CmdErrorMessages.hs @@ -72,6 +72,13 @@ renderListCommaAnd [x] = x renderListCommaAnd [x,x'] = x ++ " and " ++ x' renderListCommaAnd (x:xs) = x ++ ", " ++ renderListCommaAnd xs +renderListTabular :: [String] -> String +renderListTabular = ("\n"++) . unlines . map ("| * "++) + +renderListPretty :: [String] -> String +renderListPretty xs = if length xs > 5 then renderListTabular xs + else renderListCommaAnd xs + -- | Render a list of things in the style @blah blah; this that; and the other@ renderListSemiAnd :: [String] -> String renderListSemiAnd [] = "" diff --git a/cabal-install/src/Distribution/Client/CmdRun.hs b/cabal-install/src/Distribution/Client/CmdRun.hs index c8e79821179..9bb34b2bfd2 100644 --- a/cabal-install/src/Distribution/Client/CmdRun.hs +++ b/cabal-install/src/Distribution/Client/CmdRun.hs @@ -27,7 +27,8 @@ import Distribution.Client.CmdErrorMessages ( renderTargetSelector, showTargetSelector, renderTargetProblem, renderTargetProblemNoTargets, plural, targetSelectorPluralPkgs, - targetSelectorFilter, renderListCommaAnd ) + targetSelectorFilter, renderListCommaAnd, + renderListPretty ) import Distribution.Client.TargetProblem ( TargetProblem (..) ) @@ -42,11 +43,11 @@ import Distribution.Simple.Flag import Distribution.Simple.Command ( CommandUI(..), usageAlternatives ) import Distribution.Types.ComponentName - ( showComponentName ) + ( componentNameRaw ) import Distribution.Verbosity ( normal, silent ) import Distribution.Simple.Utils - ( wrapText, die', info, notice ) + ( wrapText, die', info, notice, safeHead ) import Distribution.Client.ProjectPlanning ( ElaboratedConfiguredPackage(..) , ElaboratedInstallPlan, binDirectoryFor ) @@ -64,6 +65,7 @@ import Distribution.Types.UnitId import Distribution.Client.ScriptUtils ( AcceptNoTargets(..), withContextAndSelectors, updateContextAndWriteProjectFile, TargetContext(..) ) +import Data.List (group) import qualified Data.Set as Set import System.Directory ( doesFileExist ) @@ -424,14 +426,13 @@ renderRunProblem :: RunProblem -> String renderRunProblem (TargetProblemMatchesMultiple targetSelector targets) = "The run command is for running a single executable at once. The target '" ++ showTargetSelector targetSelector ++ "' refers to " - ++ renderTargetSelector targetSelector ++ " which includes " - ++ renderListCommaAnd ( ("the "++) <$> - showComponentName <$> - availableTargetComponentName <$> - foldMap - (\kind -> filterTargetsKind kind targets) - [ExeKind, TestKind, BenchKind] ) - ++ "." + ++ renderTargetSelector targetSelector ++ " which includes \n" + ++ unlines ((\(label, xs) -> "- " ++ label ++ ": " ++ renderListPretty xs) + <$> (zip ["executables", "test-suites", "benchmarks"] + $ filter (not . null) . map removeDuplicates + $ map (componentNameRaw . availableTargetComponentName) + <$> (flip filterTargetsKind $ targets) <$> [ExeKind, TestKind, BenchKind] )) + where removeDuplicates = catMaybes . map safeHead . group . sort renderRunProblem (TargetProblemMultipleTargets selectorMap) = "The run command is for running a single executable at once. The targets " diff --git a/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs index 2fa5b121956..e65bb15ab97 100644 --- a/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs +++ b/cabal-install/tests/UnitTests/Distribution/Client/Init/Utils.hs @@ -67,7 +67,6 @@ baseVersion' "8.8.4" = [4,13,0,0] baseVersion' "8.6.5" = [4,12,0,0] baseVersion' "8.4.4" = [4,11,1,0] baseVersion' "8.2.2" = [4,10,1,0] -baseVersion' "8.0.2" = [4,10,0,0] baseVersion' "7.10.3" = [4,9,0,0] baseVersion' "7.8.4" = [4,8,0,0] baseVersion' "7.6.3" = [4,7,0,0] diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out b/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out index 31358efe8d1..1c5a2e37052 100644 --- a/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out +++ b/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultipleExes/cabal.out @@ -16,6 +16,8 @@ Building executable 'bar' for MultipleExes-1.0.. # cabal v2-run Up to date # cabal v2-run -Error: cabal: The run command is for running a single executable at once. The target '' refers to the package MultipleExes-1.0 which includes the executable 'foo' and the executable 'bar'. +Error: cabal: The run command is for running a single executable at once. The target '' refers to the package MultipleExes-1.0 which includes +- executables: bar and foo # cabal v2-run -Error: cabal: The run command is for running a single executable at once. The target 'MultipleExes' refers to the package MultipleExes-1.0 which includes the executable 'foo' and the executable 'bar'. +Error: cabal: The run command is for running a single executable at once. The target 'MultipleExes' refers to the package MultipleExes-1.0 which includes +- executables: bar and foo diff --git a/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out b/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out index 2d71bf5e2bb..66606e20870 100644 --- a/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out +++ b/cabal-testsuite/PackageTests/NewBuild/CmdRun/MultiplePackages/cabal.out @@ -25,7 +25,8 @@ Building executable 'foo-exe' for bar-1.0.. # cabal v2-run Error: cabal: No targets given and there is no package in the current directory. Specify packages or components by name or location. See 'cabal build --help' for more details on target options. # cabal v2-run -Error: cabal: The run command is for running a single executable at once. The target 'bar' refers to the package bar-1.0 which includes the executable 'foo-exe' and the executable 'bar-exe'. +Error: cabal: The run command is for running a single executable at once. The target 'bar' refers to the package bar-1.0 which includes +- executables: bar-exe and foo-exe # cabal v2-run Error: cabal: Ambiguous target 'foo-exe'. It could be: bar:foo-exe (component) diff --git a/changelog.d/issue-8189 b/changelog.d/issue-8189 new file mode 100644 index 00000000000..0d7372e2db7 --- /dev/null +++ b/changelog.d/issue-8189 @@ -0,0 +1,11 @@ +synopsis: Pretty-print run targets on failure +packages: cabal-install +prs: #8234 +issues: #8189 + +description: { + +- Targets of the `run` command are pretty-printed when failing due to multiple targets. +- Duplicate targets are removed in the output. + +} \ No newline at end of file