From ee65229431da974c978476fb23020ae91f4f9363 Mon Sep 17 00:00:00 2001 From: Herbert Valerio Riedel Date: Sat, 24 Feb 2018 01:02:05 +0100 Subject: [PATCH] Add `cabal get --only-package-description` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Co-authored-by: Artem Pelenitsyn --- cabal-install/src/Distribution/Client/Get.hs | 38 +++++++++++++++++-- .../src/Distribution/Client/Setup.hs | 12 ++++++ .../Get/OnlyDescription/cabal.out | 6 +++ .../Get/OnlyDescription/cabal.test.hs | 11 ++++++ .../repo/criterion-1.1.4.0/criterion.cabal | 8 ++++ changelog.d/issue-1954 | 4 ++ doc/cabal-package.rst | 3 ++ 7 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out create mode 100644 cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs create mode 100644 cabal-testsuite/PackageTests/Get/OnlyDescription/repo/criterion-1.1.4.0/criterion.cabal create mode 100644 changelog.d/issue-1954 diff --git a/cabal-install/src/Distribution/Client/Get.hs b/cabal-install/src/Distribution/Client/Get.hs index d2e08b3ef46..d5670096991 100644 --- a/cabal-install/src/Distribution/Client/Get.hs +++ b/cabal-install/src/Distribution/Client/Get.hs @@ -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 ) @@ -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 @@ -94,9 +97,17 @@ 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 @@ -104,6 +115,8 @@ get verbosity repoCtxt _ getFlags userTargets = do --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) @@ -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 -- ------------------------------------------------------------ diff --git a/cabal-install/src/Distribution/Client/Setup.hs b/cabal-install/src/Distribution/Client/Setup.hs index 3164fa5a232..a4bab24558e 100644 --- a/cabal-install/src/Distribution/Client/Setup.hs +++ b/cabal-install/src/Distribution/Client/Setup.hs @@ -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, @@ -1307,6 +1308,7 @@ data GetFlags = GetFlags { defaultGetFlags :: GetFlags defaultGetFlags = GetFlags { getDestDir = mempty, + getOnlyPkgDescr = mempty, getPristine = mempty, getIndexState = mempty, getActiveRepos = mempty, @@ -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.") diff --git a/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out b/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out new file mode 100644 index 00000000000..3b8aadfe3df --- /dev/null +++ b/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.out @@ -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 diff --git a/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs b/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs new file mode 100644 index 00000000000..3b4a36553c7 --- /dev/null +++ b/cabal-testsuite/PackageTests/Get/OnlyDescription/cabal.test.hs @@ -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" ] diff --git a/cabal-testsuite/PackageTests/Get/OnlyDescription/repo/criterion-1.1.4.0/criterion.cabal b/cabal-testsuite/PackageTests/Get/OnlyDescription/repo/criterion-1.1.4.0/criterion.cabal new file mode 100644 index 00000000000..e7cdc916530 --- /dev/null +++ b/cabal-testsuite/PackageTests/Get/OnlyDescription/repo/criterion-1.1.4.0/criterion.cabal @@ -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 diff --git a/changelog.d/issue-1954 b/changelog.d/issue-1954 new file mode 100644 index 00000000000..49650160579 --- /dev/null +++ b/changelog.d/issue-1954 @@ -0,0 +1,4 @@ +synopsis: Add `cabal get --only-package-description` +packages: cabal-install +prs: #1977 #5162 #8263 +issues: #1954 diff --git a/doc/cabal-package.rst b/doc/cabal-package.rst index bab41cdc6ef..e6a9e3e1d6f 100644 --- a/doc/cabal-package.rst +++ b/doc/cabal-package.rst @@ -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.