Skip to content

Commit 27d9dac

Browse files
committed
Add module name validation in cabal check command
This change ensures that Cabal warns about modules with names that would cause portability issues, especially on Windows systems where certain names like "aux", "con", "nul", etc. are reserved by the operating system. Fixes #10295
1 parent 44086db commit 27d9dac

File tree

8 files changed

+94
-1
lines changed

8 files changed

+94
-1
lines changed

Cabal/src/Distribution/PackageDescription/Check/Paths.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
module Distribution.PackageDescription.Check.Paths
1111
( checkGlob
1212
, checkPath
13+
, checkPackageFileNamesWithGlob
1314
, fileExtensionSupportedLanguage
1415
, isGoodRelativeDirectoryPath
1516
, isGoodRelativeFilePath

Cabal/src/Distribution/PackageDescription/Check/Target.hs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import Prelude ()
2121
import Distribution.CabalSpecVersion
2222
import Distribution.Compat.Lens
2323
import Distribution.Compiler
24-
import Distribution.ModuleName (ModuleName)
24+
import Distribution.ModuleName (ModuleName, toFilePath)
2525
import Distribution.Package
2626
import Distribution.PackageDescription
2727
import Distribution.PackageDescription.Check.Common
@@ -61,6 +61,9 @@ checkLibrary
6161
_libVisibility_
6262
libBuildInfo_
6363
) = do
64+
65+
mapM_ checkModuleName (explicitLibModules lib)
66+
6467
checkP
6568
(libName_ == LMainLibName && isSub)
6669
(PackageBuildImpossible UnnamedInternal)
@@ -144,6 +147,8 @@ checkExecutable
144147
let cet = CETExecutable exeName_
145148
modulePath_ = getSymbolicPath symbolicModulePath_
146149

150+
mapM_ checkModuleName (exeModules exe)
151+
147152
-- § Exe specific checks
148153
checkP
149154
(null modulePath_)
@@ -205,6 +210,9 @@ checkTestSuite
205210
TestSuiteUnsupported tt ->
206211
tellP (PackageBuildWarning $ TestsuiteNotSupported tt)
207212
_ -> return ()
213+
214+
mapM_ checkModuleName (testModules ts)
215+
208216
checkP
209217
mainIsWrongExt
210218
(PackageBuildImpossible NoHsLhsMain)
@@ -257,6 +265,8 @@ checkBenchmark
257265
-- Target type/name (benchmark).
258266
let cet = CETBenchmark benchmarkName_
259267

268+
mapM_ checkModuleName (benchmarkModules bm)
269+
260270
-- § Interface & bm specific tests.
261271
case benchmarkInterface_ of
262272
BenchmarkUnsupported tt@(BenchmarkTypeUnknown _ _) ->
@@ -294,6 +304,11 @@ checkBenchmark
294304
BenchmarkExeV10 _ f -> takeExtension (getSymbolicPath f) `notElem` [".hs", ".lhs"]
295305
_ -> False
296306

307+
308+
-- | Check if a module name is valid on both Windows and Posix systems
309+
checkModuleName :: Monad m => ModuleName -> CheckM m ()
310+
checkModuleName moduleName =
311+
checkPackageFileNamesWithGlob PathKindFile (toFilePath moduleName)
297312
-- ------------------------------------------------------------
298313
-- Build info
299314
-- ------------------------------------------------------------
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: InvalidModuleName
2+
version: 0.1.0.0
3+
license: BSD3
4+
license-file: LICENSE
5+
category: development
6+
author: Foo Bar
7+
maintainer: [email protected]
8+
build-type: Simple
9+
cabal-version: >=1.10
10+
synopsis: Test for invalid module names
11+
description: Tests that invalid module names are properly rejected by cabal check
12+
13+
library
14+
exposed-modules: Aux
15+
build-depends: base < 5
16+
hs-source-dirs: src
17+
default-language: Haskell2010
18+
19+
executable invalid-exe
20+
main-is: Main.hs
21+
other-modules: Exe.Aux
22+
, Exe.Aux.Test
23+
build-depends: base < 5
24+
hs-source-dirs: exe
25+
default-language: Haskell2010
26+
27+
test-suite invalid-test
28+
type: exitcode-stdio-1.0
29+
main-is: Main.hs
30+
other-modules: Test.Aux
31+
, Test.Aux.Test
32+
build-depends: base < 5
33+
hs-source-dirs: test
34+
default-language: Haskell2010
35+
36+
benchmark invalid-bench
37+
type: exitcode-stdio-1.0
38+
main-is: Main.hs
39+
other-modules: Bench.Aux
40+
, Bench.Aux.Test
41+
build-depends: base < 5
42+
hs-source-dirs: bench
43+
default-language: Haskell2010

cabal-testsuite/PackageTests/Check/InvalidModuleName/LICENSE

Whitespace-only changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import Distribution.Simple
2+
main :: IO ()
3+
main = defaultMain
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# cabal check
2+
The following errors are likely to affect your build negatively:
3+
Error: [unknown-directory] 'hs-source-dirs: bench' specifies a directory which does not exist.
4+
Error: [unknown-directory] 'hs-source-dirs: exe' specifies a directory which does not exist.
5+
Error: [unknown-directory] 'hs-source-dirs: test' specifies a directory which does not exist.
6+
The following errors will cause portability problems on other environments:
7+
Error: [invalid-path-win] The path 'Aux' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|", and there are a few reserved names including "aux", "nul", "con", "prn", "com{1-9}", "lpt{1-9}" and "clock$".
8+
Error: [invalid-path-win] The path 'Bench/Aux' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|", and there are a few reserved names including "aux", "nul", "con", "prn", "com{1-9}", "lpt{1-9}" and "clock$".
9+
Error: [invalid-path-win] The path 'Bench/Aux/Test' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|", and there are a few reserved names including "aux", "nul", "con", "prn", "com{1-9}", "lpt{1-9}" and "clock$".
10+
Error: [invalid-path-win] The path 'Exe/Aux' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|", and there are a few reserved names including "aux", "nul", "con", "prn", "com{1-9}", "lpt{1-9}" and "clock$".
11+
Error: [invalid-path-win] The path 'Exe/Aux/Test' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|", and there are a few reserved names including "aux", "nul", "con", "prn", "com{1-9}", "lpt{1-9}" and "clock$".
12+
Error: [invalid-path-win] The path 'Test/Aux' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|", and there are a few reserved names including "aux", "nul", "con", "prn", "com{1-9}", "lpt{1-9}" and "clock$".
13+
Error: [invalid-path-win] The path 'Test/Aux/Test' is invalid on Windows, which would cause portability problems for this package. Windows file names cannot contain any of the characters ":*?<>|", and there are a few reserved names including "aux", "nul", "con", "prn", "com{1-9}", "lpt{1-9}" and "clock$".
14+
Error: Hackage would reject this package.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Test.Cabal.Prelude
2+
3+
main = cabalTest $ do
4+
r <- fails $ cabal' "check" []
5+
assertOutputContains "is invalid on Windows" r
6+
assertOutputContains "Aux" r
7+
assertOutputContains "Exe/Aux" r
8+
assertOutputContains "Test/Aux" r
9+
assertOutputContains "Bench/Aux" r
10+
assertOutputContains "Exe/Aux/Test" r
11+
assertOutputContains "Test/Aux/Test" r
12+
assertOutputContains "Bench/Aux/Test" r
13+
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Aux where
2+
3+
someFunction :: Int
4+
someFunction = 42

0 commit comments

Comments
 (0)