Skip to content

Print package version #12

Description

@Vekhir

Hi,

I'd like to request (and help implement) the feature to print the package version as specified in the .cabal file.

Description

When updating the Arch ghc PKGBUILD, we need to update the provided library versions for the base libraries. This is currently done via a bash script: https://gitlab.archlinux.org/archlinux/packaging/packages/ghc/-/blob/692251015877f0aef887a16a2203351c89abc4eb/print-provides-replaces.sh#L36-37

The important part is this section:

    version=$(awk 'tolower($0) ~ /^version:/ {print $2 }' $path)
    [[ "$version" == "@ProjectVersionMunged@" || "$version" == "@ProjectVersion@" ]] && version=$pkgver

It searches each line for the "version" field and prints that version. A special case for GHC is that some libraries get their version from the GHC they ship with.
This works fine until a package like semaphore-compat lists its version on the next line.

Analysis

uusi already deals with .cabal files and is the best place for handling this.
A bit of an issue is that the munged versions aren't valid versions and thus won't be parsed. Doing the text replacement is simple enough tough, so that's probably better handled outside of this feature.

Investigation

I played around a bit with GHCi and looked at how uusi reads the .cabal files. I came up with this small script:

import qualified Data.Text.IO as T
import Distribution.Pretty (pretty)
import Distribution.Types.GenericPackageDescription (packageDescription)
import Distribution.Types.PackageDescription (package)
import Distribution.Types.PackageId(pkgVersion)
#if !MIN_VERSION_Cabal(3,8,0)
import Distribution.PackageDescription.Parsec (readGenericPackageDescription)
#else
import Distribution.Simple.PackageDescription (readGenericPackageDescription)
#endif

import qualified Distribution.Verbosity as Verbosity
import Options (runOption)
import System.Environment (getArgs)

main :: IO ()
main = do
  args <- getArgs
  (o, targets) <- runOption args

  target <- case targets of
    [x] -> pure x
    [] -> findCabal
    _ -> fail "Please specify at most one target to uusi"

  printPackageVersion target

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

printPackageVersion :: FilePath -> IO ()
printPackageVersion originPath = do

  cabal <- readGenericPackageDescription Verbosity.normal originPath
  T.putStrLn <| pretty (pkgVersion (package (packageDescription cabal)))

findCabal :: IO FilePath
findCabal =
  findPackageDesc "." >>= \case
    Left err -> fail err
    Right x -> pure x

Naming

I thought about names and I quite like ppv. A more verbose name like print-package-version is probably also fine, but sounds rather generic, which this tool wouldn't be, because it only handles Haskell libraries (and of those just the .cabal files).

Conclusion

I'll probably make a PR with this and other changes on the weekend. What do you @berberman think of this? You are certainly more familiar with this and maybe you think of a better way.

Thanks for your time,
Vekhir

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions