diff --git a/Cabal/src/Distribution/PackageDescription/Check.hs b/Cabal/src/Distribution/PackageDescription/Check.hs index f743b62365d..ee50418e928 100644 --- a/Cabal/src/Distribution/PackageDescription/Check.hs +++ b/Cabal/src/Distribution/PackageDescription/Check.hs @@ -413,9 +413,13 @@ checkPackageDescription checkPackageId package_ -- TODO `name` is caught at parse level, remove this test. let pn = packageName package_ + pns = unPackageName pn checkP - (null . unPackageName $ pn) + (null pns) (PackageBuildImpossible NoNameField) + checkP + (any (not . isAscii) pns) + (PackageDistInexcusable NonASCIIName) -- TODO `version` is caught at parse level, remove this test. checkP (nullVersion == packageVersion package_) diff --git a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs index 3ff5430eac7..6d474fab477 100644 --- a/Cabal/src/Distribution/PackageDescription/Check/Warning.hs +++ b/Cabal/src/Distribution/PackageDescription/Check/Warning.hs @@ -142,6 +142,7 @@ filterPackageChecksByIdString cs ss = data CheckExplanation = ParseWarning FilePath PWarning | NoNameField + | NonASCIIName | NoVersionField | NoTarget | UnnamedInternal @@ -309,6 +310,7 @@ extractCheckExplanation (PackageDistInexcusable e) = e data CheckExplanationID = CIParseWarning | CINoNameField + | CINonASCIIName | CINoVersionField | CINoTarget | CIUnnamedInternal @@ -455,6 +457,7 @@ data CheckExplanationID checkExplanationId :: CheckExplanation -> CheckExplanationID checkExplanationId (ParseWarning{}) = CIParseWarning checkExplanationId (NoNameField{}) = CINoNameField +checkExplanationId (NonASCIIName{}) = CINonASCIIName checkExplanationId (NoVersionField{}) = CINoVersionField checkExplanationId (NoTarget{}) = CINoTarget checkExplanationId (UnnamedInternal{}) = CIUnnamedInternal @@ -608,6 +611,7 @@ ppCheckExplanationId :: CheckExplanationID -> CheckExplanationIDString -- $ cabal run Cabal-tests:unit-tests -- --pattern=Parsimonious ppCheckExplanationId CIParseWarning = "parser-warning" ppCheckExplanationId CINoNameField = "no-name-field" +ppCheckExplanationId CINonASCIIName = "non-ascii-name" ppCheckExplanationId CINoVersionField = "no-version-field" ppCheckExplanationId CINoTarget = "no-target" ppCheckExplanationId CIUnnamedInternal = "unnamed-internal-library" @@ -795,6 +799,7 @@ ppWarnLang LangCPlusPlus = "C++" ppExplanation :: CheckExplanation -> String ppExplanation (ParseWarning fp pp) = showPWarning fp pp ppExplanation NoNameField = "No 'name' field." +ppExplanation NonASCIIName = "Non-ASCII characters in 'name' field." ppExplanation NoVersionField = "No 'version' field." ppExplanation NoTarget = "No executables, libraries, tests, or benchmarks found. Nothing to do." diff --git a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/cabal.out b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/cabal.out new file mode 100644 index 00000000000..6064676ea62 --- /dev/null +++ b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/cabal.out @@ -0,0 +1,5 @@ +# cabal check +The following errors will cause portability problems on other environments: +Error: [name-no-match] The filename './pkg.cabal' does not match package name (expected: 'pkg-?.cabal') +Error: [non-ascii-name] Non-ASCII characters in 'name' field. +Error: Hackage would reject this package. diff --git a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/cabal.test.hs b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/cabal.test.hs new file mode 100644 index 00000000000..5d037e67116 --- /dev/null +++ b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/cabal.test.hs @@ -0,0 +1,5 @@ +import Test.Cabal.Prelude + +-- Non ASCII charaters in package name. +main = cabalTest $ + fails $ cabal "check" [] diff --git a/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/pkg.cabal b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/pkg.cabal new file mode 100644 index 00000000000..71532e30e51 --- /dev/null +++ b/cabal-testsuite/PackageTests/Check/ConfiguredPackage/Fields/NonASCIIName/pkg.cabal @@ -0,0 +1,16 @@ +cabal-version: 3.0 +name: pkg-α + -- Cabal testsuite sadly chokes when copying files with + -- non-ASCII characters in them. So for this test, in + -- the output file, you will get an error for filename/ + -- name mismatch, too. +description: description +synopsis: synopsis +version: 0 +category: example +maintainer: none@example.com +license: GPL-3.0-or-later + +library + exposed-modules: Module + default-language: Haskell2010 diff --git a/changelog.d/pr-11198 b/changelog.d/pr-11198 new file mode 100644 index 00000000000..7b534e22e37 --- /dev/null +++ b/changelog.d/pr-11198 @@ -0,0 +1,9 @@ +--- +synopsis: Warn on non-ASCII characters in `name` +packages: [Cabal, cabal-install] +prs: 11198 +issues: 11197 +--- + +`cabal check` now warns about packages with non-ASCII characters +in their name (they are not accepted by Hackage). diff --git a/doc/cabal-commands.rst b/doc/cabal-commands.rst index b9354db992d..23adbeef1b4 100644 --- a/doc/cabal-commands.rst +++ b/doc/cabal-commands.rst @@ -1385,6 +1385,7 @@ A list of all warnings with their constructor: - ``parser-warning``: inherited from parser. - ``no-name-field``: missing ``name`` field. +- ``non-ascii-name``: non-ASCII characters in ``name`` field. - ``no-version-field``: missing ``version`` field. - ``no-target``: missing target in ``.cabal``. - ``unnamed-internal-library``: unnamed internal library.