Skip to content

Commit 3824275

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 3824275

7 files changed

Lines changed: 110 additions & 1 deletion

File tree

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: 15 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,8 @@ checkLibrary
6161
_libVisibility_
6262
libBuildInfo_
6363
) = do
64+
mapM_ checkModuleName (explicitLibModules lib)
65+
6466
checkP
6567
(libName_ == LMainLibName && isSub)
6668
(PackageBuildImpossible UnnamedInternal)
@@ -144,6 +146,8 @@ checkExecutable
144146
let cet = CETExecutable exeName_
145147
modulePath_ = getSymbolicPath symbolicModulePath_
146148

149+
mapM_ checkModuleName (exeModules exe)
150+
147151
-- § Exe specific checks
148152
checkP
149153
(null modulePath_)
@@ -205,6 +209,9 @@ checkTestSuite
205209
TestSuiteUnsupported tt ->
206210
tellP (PackageBuildWarning $ TestsuiteNotSupported tt)
207211
_ -> return ()
212+
213+
mapM_ checkModuleName (testModules ts)
214+
208215
checkP
209216
mainIsWrongExt
210217
(PackageBuildImpossible NoHsLhsMain)
@@ -257,6 +264,8 @@ checkBenchmark
257264
-- Target type/name (benchmark).
258265
let cet = CETBenchmark benchmarkName_
259266

267+
mapM_ checkModuleName (benchmarkModules bm)
268+
260269
-- § Interface & bm specific tests.
261270
case benchmarkInterface_ of
262271
BenchmarkUnsupported tt@(BenchmarkTypeUnknown _ _) ->
@@ -294,6 +303,11 @@ checkBenchmark
294303
BenchmarkExeV10 _ f -> takeExtension (getSymbolicPath f) `notElem` [".hs", ".lhs"]
295304
_ -> False
296305

306+
-- | Check if a module name is valid on both Windows and Posix systems
307+
checkModuleName :: Monad m => ModuleName -> CheckM m ()
308+
checkModuleName moduleName =
309+
checkPackageFileNamesWithGlob PathKindFile (toFilePath moduleName)
310+
297311
-- ------------------------------------------------------------
298312
-- Build info
299313
-- ------------------------------------------------------------
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
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: cabal-dev@haskell.org
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
44+

cabal-testsuite/PackageTests/Check/InvalidModuleName/LICENSE

Whitespace-only changes.
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+

changelog.d/pr-10816.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
synopsis: "Add checks for Windows reserved filenames in module paths"
2+
packages: Cabal cabal-install
3+
prs: #10816
4+
issues: #10295
5+
6+
description: {
7+
8+
On Windows, certain filenames are reserved by the operating system such as
9+
"aux", "con", "prn", "nul", etc. When these names appear in module paths they
10+
can cause build failures on Windows systems.
11+
12+
`cabal check` now properly warns about module paths that contain Windows reserved
13+
filenames, not just filepaths which contain these reserved tokens. These warnings
14+
are controlled by the existing `invalid-win-path` category.
15+
16+
For example, module paths like:
17+
- `Exe.Aux.Test`
18+
- `Test.Aux.Module`
19+
- `Bench.Aux.Helpers`
20+
21+
will now trigger appropriate warnings during `cabal check`.
22+
23+
}

0 commit comments

Comments
 (0)