Skip to content

Commit

Permalink
Add cabal get --only-package-description (#8263)
Browse files Browse the repository at this point in the history
With this option, 'cabal get' writes to the destination directory only the
package description already available locally in one of the repository
indices.

The basename of the file name written to inside the target directory is
the package-id rather than only the package name.

This is mostly based on #1977

Co-authored-by: Miëtek Bak <mietek@bak.io>
Co-authored-by: Artem Pelenitsyn <a.pelenitsyn@gmail.com>

Co-authored-by: Herbert Valerio Riedel <hvr@gnu.org>
Co-authored-by: Miëtek Bak <mietek@bak.io>
  • Loading branch information
3 people committed Jul 4, 2022
1 parent 0c4d048 commit da68c28
Show file tree
Hide file tree
Showing 8 changed files with 82 additions and 4 deletions.
38 changes: 34 additions & 4 deletions cabal-install/src/Distribution/Client/Get.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import Distribution.Package
import Distribution.Simple.Setup
( Flag(..), fromFlag, fromFlagOrDefault, flagToMaybe )
import Distribution.Simple.Utils
( notice, die', info, writeFileAtomic )
( notice, die', info, warn, writeFileAtomic )
import qualified Distribution.PackageDescription as PD
import Distribution.Simple.Program
( programName )
Expand All @@ -49,8 +49,11 @@ import qualified Distribution.Client.Tar as Tar (extractTarGzFile)
import Distribution.Client.IndexUtils
( getSourcePackagesAtIndexState, TotalIndexState, ActiveRepos )
import Distribution.Solver.Types.SourcePackage
import Distribution.PackageDescription.PrettyPrint
( writeGenericPackageDescription )

import qualified Data.Map as Map
import Control.Monad ( mapM_ )
import System.Directory
( createDirectoryIfMissing, doesDirectoryExist, doesFileExist )
import System.FilePath
Expand Down Expand Up @@ -94,16 +97,26 @@ get verbosity repoCtxt _ getFlags userTargets = do
unless (null prefix) $
createDirectoryIfMissing True prefix

if useSourceRepo
then clone pkgs
else unpack pkgs
if onlyPkgDescr
then do
when useSourceRepo $
warn verbosity $
"Ignoring --source-repository for --only-package-description"

mapM_ (unpackOnlyPkgDescr verbosity prefix) pkgs
else
if useSourceRepo
then clone pkgs
else unpack pkgs

where
resolverParams :: SourcePackageDb -> [PackageSpecifier UnresolvedSourcePackage] -> DepResolverParams
resolverParams sourcePkgDb pkgSpecifiers =
--TODO: add command-line constraint and preference args for unpack
standardInstallPolicy mempty sourcePkgDb pkgSpecifiers

onlyPkgDescr = fromFlagOrDefault False (getOnlyPkgDescr getFlags)

prefix :: String
prefix = fromFlagOrDefault "" (getDestDir getFlags)

Expand Down Expand Up @@ -189,6 +202,23 @@ unpackPackage verbosity prefix pkgid descOverride pkgPath = do
writeFileAtomic descFilePath pkgtxt


-- | Write a @pkgId.cabal@ file with the package description to the destination
-- directory, unless one already exists.
unpackOnlyPkgDescr :: Verbosity -> FilePath -> UnresolvedSourcePackage -> IO ()
unpackOnlyPkgDescr verbosity dstDir pkg = do
let pkgFile = dstDir </> prettyShow (packageId pkg) <.> "cabal"
existsFile <- doesFileExist pkgFile
when existsFile $ die' verbosity $
"The file \"" ++ pkgFile ++ "\" already exists, not overwriting."
existsDir <- doesDirectoryExist (addTrailingPathSeparator pkgFile)
when existsDir $ die' verbosity $
"A directory \"" ++ pkgFile ++ "\" is in the way, not unpacking."
notice verbosity $ "Writing package description to " ++ pkgFile
case srcpkgDescrOverride pkg of
Just pkgTxt -> writeFileAtomic pkgFile pkgTxt
Nothing ->
writeGenericPackageDescription pkgFile (srcpkgDescription pkg)

-- ------------------------------------------------------------
-- * Cloning packages from their declared source repositories
-- ------------------------------------------------------------
Expand Down
12 changes: 12 additions & 0 deletions cabal-install/src/Distribution/Client/Setup.hs
Original file line number Diff line number Diff line change
Expand Up @@ -1297,6 +1297,7 @@ instance Semigroup ReportFlags where

data GetFlags = GetFlags {
getDestDir :: Flag FilePath,
getOnlyPkgDescr :: Flag Bool,
getPristine :: Flag Bool,
getIndexState :: Flag TotalIndexState,
getActiveRepos :: Flag ActiveRepos,
Expand All @@ -1307,6 +1308,7 @@ data GetFlags = GetFlags {
defaultGetFlags :: GetFlags
defaultGetFlags = GetFlags {
getDestDir = mempty,
getOnlyPkgDescr = mempty,
getPristine = mempty,
getIndexState = mempty,
getActiveRepos = mempty,
Expand Down Expand Up @@ -1352,6 +1354,16 @@ getCommand = CommandUI {
(toFlag `fmap` parsec))
(flagToList . fmap prettyShow))

, option [] ["only-package-description"]
"Unpack only the package description file."
getOnlyPkgDescr (\v flags -> flags { getOnlyPkgDescr = v })
trueArg

, option [] ["package-description-only"]
"A synonym for --only-package-description."
getOnlyPkgDescr (\v flags -> flags { getOnlyPkgDescr = v })
trueArg

, option [] ["pristine"]
("Unpack the original pristine tarball, rather than updating the "
++ ".cabal file with the latest revision from the package archive.")
Expand Down
6 changes: 6 additions & 0 deletions cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# cabal v2-update
Downloading the latest package list from test-local-repo
# cabal update
Downloading the latest package list from test-local-repo
# cabal get
Writing package description to criterion-1.1.4.0.cabal
11 changes: 11 additions & 0 deletions cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
-- 2022-07-03, issue #1954
--
-- Purpose of this test:
-- Make sure that `cabal get --only-package-description` works

import Test.Cabal.Prelude
main = cabalTest $ withRepo "repo" $ do
cabal "update" []
cabal
"get"
[ "criterion", "--only-package-description" ]
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
name: criterion
version: 1.1.4.0
build-type: Simple
cabal-version: >= 1.10

library
build-depends: base, ghc-prim
default-language: Haskell2010
4 changes: 4 additions & 0 deletions changelog.d/issue-1954
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
synopsis: Add `cabal get --only-package-description`
packages: cabal-install
prs: #1977 #5162 #8263
issues: #1954
4 changes: 4 additions & 0 deletions changelog.d/issue-7462
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
synopsis: `cabal haddock` now implies `--enable-documentation`
packages: Cabal
issues: #1919
prs: #7827
3 changes: 3 additions & 0 deletions doc/cabal-package.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2865,6 +2865,9 @@ The ``get`` command supports the following options:
``2016-09-24T17:47:48Z``), or ``HEAD`` (default).
This determines which package versions are available as well as which
``.cabal`` file revision is selected (unless ``--pristine`` is used).
``--only-package-description``
Unpack only the package description file. A synonym,
``--package-description-only``, is provided for convenience.
``--pristine``
Unpack the original pristine tarball, rather than updating the
``.cabal`` file with the latest revision from the package archive.
Expand Down

0 comments on commit da68c28

Please sign in to comment.