Skip to content

Commit

Permalink
Fix --project-file behaviour.
Browse files Browse the repository at this point in the history
- This commit sets the ProjectRoot consistently for both absolute
  and relative --project-file pats. The ProjectRoot is set as the
  directory where the --project-file is located.
- Before this change relative project files are rooted to where the
  project file is resolved, when recursively searching upward from
  the current directory, and not where it is located.

  Previous behaviour is as follows,

  gitpod ~/0/1/2/foo $ tree ~/0
  /home/gitpod/0
  └── 1
      ├── 2
      │   └── foo
      │       ├── app
      │       │   └── Main.hs
      │       ├── CHANGELOG.md
      │       └── foo.cabal
      └── cabal.project

  and inside foo let's run

  $ pwd
  /home/gitpod/0/1/2/foo
  $ cabal build all --project-file ../cabal.project

  which builds the project setting the project root at 2 using
  the project file at 1

  $ ls ~/0/1 ~/0/1/2
  /home/gitpod/0/1:
  2  cabal.project

  /home/gitpod/0/1/2:
  dist-newstyle foo

  However, if the cabal.project file was instead in 0 directory,
  cabal would fail to build since the resolved project root is at
  1 and cabal fails to find a package at 1/foo

  gitpod ~/0/1/2/foo $ mv ~/0/1/cabal.project ~/0/
  gitpod ~/0/1/2/foo $ cabal build all --project-file ../cabal.project
  When using configuration(s) from /home/gitpod/0/1/../cabal.project, the following errors occurred:
  The package location 'foo' does not exist.

  This beaviour is almost never what we want.
  • Loading branch information
pranaysashank committed Oct 14, 2021
1 parent 3f1a5f2 commit 49004bf
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 11 deletions.
11 changes: 4 additions & 7 deletions cabal-install/src/Distribution/Client/ProjectConfig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -406,8 +406,7 @@ resolveBuildTimeSettings verbosity
findProjectRoot :: Maybe FilePath -- ^ starting directory, or current directory
-> Maybe FilePath -- ^ @cabal.project@ file name override
-> IO (Either BadProjectRoot ProjectRoot)
findProjectRoot _ (Just projectFile)
| isAbsolute projectFile = do
findProjectRoot _ (Just projectFile) = do
exists <- doesFileExist projectFile
if exists
then do projectFile' <- canonicalizePath projectFile
Expand All @@ -416,13 +415,13 @@ findProjectRoot _ (Just projectFile)
return (Right projectRoot)
else return (Left (BadProjectRootExplicitFile projectFile))

findProjectRoot mstartdir mprojectFile = do
findProjectRoot mstartdir Nothing = do
startdir <- maybe getCurrentDirectory canonicalizePath mstartdir
homedir <- getHomeDirectory
probe startdir homedir
where
projectFileName :: String
projectFileName = fromMaybe "cabal.project" mprojectFile
projectFileName = "cabal.project"

-- Search upwards. If we get to the users home dir or the filesystem root,
-- then use the current dir
Expand All @@ -431,9 +430,7 @@ findProjectRoot mstartdir mprojectFile = do
where
go :: FilePath -> IO (Either BadProjectRoot ProjectRoot)
go dir | isDrive dir || dir == homedir =
case mprojectFile of
Nothing -> return (Right (ProjectRootImplicit startdir))
Just file -> return (Left (BadProjectRootExplicitFile file))
return (Right (ProjectRootImplicit startdir))
go dir = do
exists <- doesFileExist (dir </> projectFileName)
if exists
Expand Down
12 changes: 8 additions & 4 deletions doc/cabal-project.rst
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,14 @@ package, and thus apply globally:
``--project-file=my.project``, then the other files that will
be probed are ``my.project.freeze`` and ``my.project.local``.

If the specified project file is a relative path, we will
look for the file relative to the current working directory,
and then for the parent directory, until the project file is
found or we have hit the top of the user's home directory.
The location of the ``--project-file`` also dictates the project
root with respect to which all other locations, like packages, are
resolved.

If a project file is not specified, we will look for the file relative
to the current working directory, and then for the parent directory,
until the project file is found or we have hit the top of the user's
home directory.

This option cannot be specified via a ``cabal.project`` file.

Expand Down

0 comments on commit 49004bf

Please sign in to comment.