Skip to content

Commit

Permalink
Warn if builddir is going to be ignored (#8949)
Browse files Browse the repository at this point in the history
* Unify the default project with the implicit one

Passing --ignore-project made cabal use `defaultProject` which is not
quite identical to the one used when cabal.project is missing
(`defaultImplifictProjectConfig`). There is no reason the two should be
different.

* Warn if builddir is going to be ignored.

builddir can only be specified from the command line.

Closes: #7941

* Clarify which project option can only be passed from the command line

* Add note about reading the project configuration
  • Loading branch information
andreabedini authored May 31, 2023
1 parent 4a99076 commit eaa38b6
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 39 deletions.
27 changes: 13 additions & 14 deletions cabal-install/src/Distribution/Client/ProjectConfig.hs
Original file line number Diff line number Diff line change
Expand Up @@ -664,18 +664,15 @@ readProjectConfig
-> Flag FilePath
-> DistDirLayout
-> Rebuild ProjectConfigSkeleton
readProjectConfig verbosity httpTransport ignoreProjectFlag configFileFlag distDirLayout = do
let defaultProject =
mempty
{ projectPackages = ["./"]
}
readProjectConfig verbosity _ (Flag True) configFileFlag _ = do
global <- singletonProjectConfigSkeleton <$> readGlobalConfig verbosity configFileFlag
return (global <> singletonProjectConfigSkeleton defaultImplicitProjectConfig)
readProjectConfig verbosity httpTransport _ configFileFlag distDirLayout = do
global <- singletonProjectConfigSkeleton <$> readGlobalConfig verbosity configFileFlag
local <- readProjectLocalConfigOrDefault verbosity httpTransport distDirLayout
freeze <- readProjectLocalFreezeConfig verbosity httpTransport distDirLayout
extra <- readProjectLocalExtraConfig verbosity httpTransport distDirLayout
if ignoreProjectFlag == Flag True
then return (global <> singletonProjectConfigSkeleton defaultProject)
else return (global <> local <> freeze <> extra)
return (global <> local <> freeze <> extra)

-- | Reads an explicit @cabal.project@ file in the given project root dir,
-- or returns the default project config for an implicitly defined project.
Expand All @@ -687,19 +684,21 @@ readProjectLocalConfigOrDefault
readProjectLocalConfigOrDefault verbosity httpTransport distDirLayout = do
let projectFile = distProjectFile distDirLayout ""
usesExplicitProjectRoot <- liftIO $ doesFileExist projectFile
let defaultImplicitProjectConfig =
mempty
{ -- We expect a package in the current directory.
projectPackages = ["./*.cabal"]
, projectConfigProvenance = Set.singleton Implicit
}
if usesExplicitProjectRoot
then do
readProjectFileSkeleton verbosity httpTransport distDirLayout "" "project file"
else do
monitorFiles [monitorNonExistentFile projectFile]
return (singletonProjectConfigSkeleton defaultImplicitProjectConfig)

defaultImplicitProjectConfig :: ProjectConfig
defaultImplicitProjectConfig =
mempty
{ -- We expect a package in the current directory.
projectPackages = ["./*.cabal"]
, projectConfigProvenance = Set.singleton Implicit
}

-- | Reads a @cabal.project.local@ file in the given project root dir,
-- or returns empty. This file gets written by @cabal configure@, or in
-- principle can be edited manually or by other tools.
Expand Down
44 changes: 39 additions & 5 deletions cabal-install/src/Distribution/Client/ProjectPlanning.hs
Original file line number Diff line number Diff line change
Expand Up @@ -331,11 +331,37 @@ sanityCheckElaboratedPackage
`optStanzaSetIsSubset` pkgStanzasEnabled
)

------------------------------------------------------------------------------

-- * Deciding what to do: making an 'ElaboratedInstallPlan'

------------------------------------------------------------------------------
-- Note [reading project configuration]
--
-- The project configuration is assembled into a ProjectConfig as follows:
--
-- CLI arguments are converted using commandLineFlagsToProjectConfig in the
-- v2 command entrypoints and passed to establishProjectBaseContext which
-- then calls rebuildProjectConfig.
--
-- rebuildProjectConfig then calls readProjectConfig to read the project
-- files. Because of conditionals, this output is in the form of a
-- ProjectConfigSkeleton and will be resolved by rebuildProjectConfig using
-- instantiateProjectConfigSkeletonFetchingCompiler.
--
-- readProjectConfig also loads the global configuration, which is read with
-- loadConfig and convertd to a ProjectConfig with convertLegacyGlobalConfig.
--
-- *Important*
--
-- You can notice how some project config options are needed to read the
-- project config! This is evident by the fact that rebuildProjectConfig
-- takes HttpTransport and DistDirLayout as parameters. Two arguments are
-- infact determined from the CLI alone (in establishProjectBaseContext).
-- Consequently, project files (including global configuration) cannot
-- affect those parameters.
--
-- Furthermore, the project configuration can specify a compiler to use,
-- which we need to resolve the conditionals in the project configuration!
-- To solve this, we configure the compiler from what is obtained by applying
-- the CLI configuration over the the configuration obtained by "flattening"
-- ProjectConfigSkeleton. This means collapsing all conditionals by taking
-- both branches.

-- | Return the up-to-date project config and information about the local
-- packages within the project.
Expand Down Expand Up @@ -390,6 +416,9 @@ rebuildProjectConfig
pure (os, arch, compilerInfo compiler)

projectConfig <- instantiateProjectConfigSkeletonFetchingCompiler fetchCompiler mempty projectConfigSkeleton
when (projectConfigDistDir (projectConfigShared $ projectConfig) /= NoFlag) $
liftIO $
warn verbosity "The builddir option is not supported in project and config files. It will be ignored."
localPackages <- phaseReadLocalPackages (projectConfig <> cliConfig)
return (projectConfig, localPackages)

Expand Down Expand Up @@ -510,6 +539,11 @@ configureCompiler
)
$ defaultProgramDb


------------------------------------------------------------------------------
-- * Deciding what to do: making an 'ElaboratedInstallPlan'
------------------------------------------------------------------------------

-- | Return an up-to-date elaborated install plan.
--
-- Two variants of the install plan are returned: with and without packages
Expand Down
6 changes: 6 additions & 0 deletions cabal-testsuite/PackageTests/Project/WarnBuilddir/cabal.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# cabal v2-build
Warning: The builddir option is not supported in project and config files. It will be ignored.
Resolving dependencies...
Build profile: -w ghc-<GHCVER> -O1
In order, the following would be built:
- main-0.1 (lib) (first run)
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
packages: .
builddir: something
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import Test.Cabal.Prelude

main = cabalTest $ do
cabal "v2-build" ["--dry-run", "all"]
14 changes: 14 additions & 0 deletions cabal-testsuite/PackageTests/Project/WarnBuilddir/main.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
cabal-version: 3.0

name: main
version: 0.1
build-type: Simple
category: Test
maintainer: Joe
synopsis: Test input
description: Test input
license: BSD-3-Clause

library
build-depends: base
default-language: Haskell2010
11 changes: 11 additions & 0 deletions changelog.d/pr-8949
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
synopsis: Warn when project configuration options are going to be ignored.
packages: cabal-install
prs: #8949

description: {

Some project configuration options can only be specified from the command line.
If the user specified those options from a project file, cabal-install would
silently ignore them. Now cabal-install will emit a warning.

}
36 changes: 16 additions & 20 deletions doc/cabal-project.rst
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ package, and thus apply globally:
to the root of the project (i.e., where the ``cabal.project``
file lives.)

This option cannot be specified via a ``cabal.project`` file.
This option can only be specified from the command line.

.. _cmdoption-project-dir:
.. option:: --project-dir=DIR
Expand All @@ -297,9 +297,9 @@ package, and thus apply globally:
:ref:`project-file<cmdoption-project-file>` path is also specified,
it will be resolved relative to this directory.

The project directory need not contain a ``cabal.project`` file.
The project directory does not need to contain a ``cabal.project`` file.

This option cannot be specified via a ``cabal.project`` file.
This option can only be specified from the command line.

.. _cmdoption-project-file:
.. option:: --project-file=FILE
Expand All @@ -318,7 +318,7 @@ package, and thus apply globally:
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.
This option can only be specified from the command line.

.. option:: --ignore-project

Expand Down Expand Up @@ -880,21 +880,7 @@ feature was added.
The command line variant of this flag is ``--enable-benchmarks`` and
``--disable-benchmarks``.

.. cfg-field:: multi-repl: boolean
--enable-multi-repl
--disable-multi-repl
:synopsis: Enable starting a repl with multiple targets.

:default: ``False``

Allow starting GHCi with multiple targets. This requires GHC with multiple
home unit support (GHC-9.4+).

The closure of required components will be loaded.

The command line variant of this flag is ``--enable-multi-repl`` and
``--disable-multi-repl``.

.. _cmdoption-extra-prog-path:
.. cfg-field:: extra-prog-path: paths (newline or comma separated)
--extra-prog-path=PATH
:synopsis: Add directories to program search path.
Expand All @@ -909,6 +895,10 @@ feature was added.
The command line variant of this flag is ``--extra-prog-path=PATH``,
which can be specified multiple times.

When specifying :ref:`--http-transport<cmdoption-http-transport>` from the
command line, only extra-prog-path from the command line are added to the
program search path.

.. cfg-field:: run-tests: boolean
--run-tests
:synopsis: Run package test suite upon installation.
Expand Down Expand Up @@ -1587,7 +1577,7 @@ Advanced global configuration options
The format and fields of the generated build information is currently experimental,
in the future we might add or remove fields, depending on the needs of other tooling.


.. _cmdoption-http-transport:
.. cfg-field:: http-transport: curl, wget, powershell, or plain-http
--http-transport=transport
:synopsis: Transport to use with http(s) requests.
Expand All @@ -1598,6 +1588,12 @@ Advanced global configuration options

The command line variant of this field is ``--http-transport=curl``.

If the project configuration imports remote urls, the user can only specify
the http-transport option from the command line.

When specifying the http-transport from the command line, the program
search path can only be influenced using :ref:`--extra-prog-path<cmdoption-extra-prog-path>`.

.. cfg-field:: ignore-expiry: boolean
--ignore-expiry
:synopsis: Ignore Hackage expiration dates.
Expand Down

0 comments on commit eaa38b6

Please sign in to comment.