| Copyright | 2021 Thomas Bidne |
|---|---|
| License | BSD-3-Clause |
| Stability | experimental |
| Safe Haskell | Safe-Inferred |
| Language | Haskell2010 |
Data.Version.Package
Description
This module provides functionality for reading a package's version
at compile-time, along with a type representing PVP version numbers.
If only the former is of interest then see packageVersionStringTH, as
this is likely the most useful function.
Since: 0.1.0.0
Synopsis
- data PackageVersion where
- pattern MkPackageVersion :: [Int] -> PackageVersion
- mkPackageVersion :: [Int] -> Either ValidationError PackageVersion
- mkPackageVersionTH :: [Int] -> Code Q PackageVersion
- unsafePackageVersion :: [Int] -> PackageVersion
- fromVersion :: Version -> Either ValidationError PackageVersion
- fromString :: String -> Either ReadStringError PackageVersion
- fromText :: Text -> Either ReadStringError PackageVersion
- unPackageVersion :: PackageVersion -> [Int]
- toVersion :: PackageVersion -> Version
- toString :: PackageVersion -> String
- toText :: PackageVersion -> Text
- packageVersionTH :: FilePath -> Code Q PackageVersion
- packageVersionStringTH :: FilePath -> Code Q String
- packageVersionTextTH :: FilePath -> Code Q Text
- packageVersionThrowIO :: FilePath -> IO PackageVersion
- packageVersionStringIO :: FilePath -> IO String
- packageVersionTextIO :: FilePath -> IO Text
- packageVersionEitherIO :: FilePath -> IO (Either ReadFileError PackageVersion)
- data ValidationError
- = VTooShortErr [Int]
- | VNegativeErr Int
- data ReadStringError
- data ReadFileError
Type
data PackageVersion where Source #
PackageVersion represents PVP version
numbers. It is similar to Data.Version's Version (i.e. wraps a
[) except:Int]
PackageVersionhas noversionTags.- We enforce PVP's "tags must be at least A.B" invariant via the smart-constructor pattern.
- Trailing zeroes are ignored in
Eq,Ord,Semigroup, andMonoid.
That is, we declare an equivalence class up to trailing zeroes.
In particular, the Monoid identity is
[0] = { [0,0], [0,0,0], ... }
and its Semigroup instance takes the greatest version (based on Ord).
Note: Because we export the underlying list in various ways,
(e.g. show), Eq's extensionality law,
x == y ==> f x == f y
can be broken. Take care that you do not rely on this law if you are
using its underlying [ (or Int]String) representation.
Examples
>>>UnsafePackageVersion [0,0,0,0] == UnsafePackageVersion [0,0,0]True
>>>UnsafePackageVersion [4,0,0] > UnsafePackageVersion [1,2,0,0]True
>>>UnsafePackageVersion [5,6,0] <> UnsafePackageVersion [9,0,0]UnsafePackageVersion {unPackageVersion = [9,0,0]}
>>>UnsafePackageVersion [0,9] <> UnsafePackageVersion [0,9,0,0]UnsafePackageVersion {unPackageVersion = [0,9]}
>>>TR.readEither @PackageVersion "UnsafePackageVersion {unPackageVersion = [3,2,1]}"Right (UnsafePackageVersion {unPackageVersion = [3,2,1]})
>>>TR.readEither @PackageVersion "UnsafePackageVersion {unPackageVersion = [3]}"Left "Prelude.read: no parse"
Since: 0.1.0.0
Bundled Patterns
| pattern MkPackageVersion :: [Int] -> PackageVersion | Since: 0.1.0.0 |
Instances
Creation
mkPackageVersion :: [Int] -> Either ValidationError PackageVersion Source #
Smart constructor for PackageVersion. The length of the list must be
> 1 to match PVP's minimal A.B. Furthermore, all digits must be non-negative.
Examples
>>>mkPackageVersion [1,2]Right (UnsafePackageVersion {unPackageVersion = [1,2]})
>>>mkPackageVersion [2,87,7,1]Right (UnsafePackageVersion {unPackageVersion = [2,87,7,1]})
>>>mkPackageVersion [1,2,-3,-4,5]Left (VNegativeErr (-3))
>>>mkPackageVersion [3]Left (VTooShortErr [3])
>>>mkPackageVersion []Left (VTooShortErr [])
Since: 0.1.0.0
mkPackageVersionTH :: [Int] -> Code Q PackageVersion Source #
Safely constructs a PackageVersion at compile-time.
Examples
>>>$$(mkPackageVersionTH [2,4,0])UnsafePackageVersion {unPackageVersion = [2,4,0]}
Since: 0.1.0.0
unsafePackageVersion :: [Int] -> PackageVersion Source #
Unsafe version of mkPackageVersion, intended to be used with
known constants. Maybe you should use mkPackageVersionTH?
WARNING: This function is not total. Exercise restraint!
Examples
>>>unsafePackageVersion [1,2,3]UnsafePackageVersion {unPackageVersion = [1,2,3]}
Since: 0.1.0.0
fromVersion :: Version -> Either ValidationError PackageVersion Source #
Creates a PackageVersion from Version.
Note: Because PackageVersion does not have a versionTags, fromVersion
is not injective even on "well-formed" Versions (i.e. non-negative and length > 1).
That is, is not an isomorphism.toVersion . fromVersion
Examples
>>>fromVersion (Version [2,13,0] ["alpha"])Right (UnsafePackageVersion {unPackageVersion = [2,13,0]})
>>>fromVersion (Version [] [])Left (VTooShortErr [])
Since: 0.1.0.0
fromString :: String -> Either ReadStringError PackageVersion Source #
Attempts to read a String into a PackageVersion. Leading and/or
trailing dots will result in an error, as will the empty string.
Examples
>>>fromString "1.4.27.3"Right (UnsafePackageVersion {unPackageVersion = [1,4,27,3]})
>>>fromString ""Left (RsReadStrErr "Prelude.read: no parse")
>>>fromString "1.a.2"Left (RsReadStrErr "Prelude.read: no parse")
>>>fromString ".1.2"Left (RsReadStrErr "Prelude.read: no parse")
>>>fromString "1.2."Left (RsReadStrErr "Prelude.read: no parse")
>>>fromString "1"Left (RsValidateErr (VTooShortErr [1]))
>>>fromString "-3.1.2"Left (RsValidateErr (VNegativeErr (-3)))
Since: 0.1.0.0
fromText :: Text -> Either ReadStringError PackageVersion Source #
Attempts to read a Text into a PackageVersion. Leading and/or
trailing dots will result in an error, as will the empty string.
Examples
>>>fromText "1.4.27.3"Right (UnsafePackageVersion {unPackageVersion = [1,4,27,3]})
>>>fromText ""Left (RsReadStrErr "Prelude.read: no parse")
>>>fromText "1.a.2"Left (RsReadStrErr "Prelude.read: no parse")
>>>fromText ".1.2"Left (RsReadStrErr "Prelude.read: no parse")
>>>fromText "1.2."Left (RsReadStrErr "Prelude.read: no parse")
>>>fromText "1"Left (RsValidateErr (VTooShortErr [1]))
>>>fromText "-3.1.2"Left (RsValidateErr (VNegativeErr (-3)))
Since: 0.1.0.0
Elimination
unPackageVersion :: PackageVersion -> [Int] Source #
Since: 0.1.0.0
toVersion :: PackageVersion -> Version Source #
Creates a Version with empty versionTags from PackageVersion.
Examples
>>>toVersion (UnsafePackageVersion [3,2,0])Version {versionBranch = [3,2,0], versionTags = []}
Since: 0.1.0.0
toString :: PackageVersion -> String Source #
Displays PackageVersion in String format.
Examples
>>>toString (UnsafePackageVersion [2,7,10,0])"2.7.10.0"
Since: 0.1.0.0
toText :: PackageVersion -> Text Source #
Displays PackageVersion in Text format.
Examples
>>>toText (UnsafePackageVersion [2,7,10,0])"2.7.10.0"
Since: 0.1.0.0
Reading Cabal Files
TemplateHaskell
These functions allow for reading a cabal's version at compile-time. If
the intention is to simply read the value so it can be printed during
runtime (e.g. for an executable's --version flag), then
packageVersionStringTH (or packageVersionTextTH) is the best choice,
as any errors encountered will not prevent compilation.
packageVersionTH :: FilePath -> Code Q PackageVersion Source #
TemplateHaskell for reading the cabal file's version at compile-time. Errors encountered will be returned as compilation errors.
Examples
>>>$$(packageVersionTH "package-version.cabal")UnsafePackageVersion {unPackageVersion = [0,1,0,0]}
Since: 0.1.0.0
packageVersionStringTH :: FilePath -> Code Q String Source #
Version of packageVersionTH that returns a String representation of
PackageVersion at compile-time. Returns "UNKNOWN" if any errors are
encountered.
Examples
>>>$$(packageVersionStringTH "package-version.cabal")"0.1.0.0"
>>>$$(packageVersionStringTH "not-found.cabal")"UNKNOWN"
Since: 0.1.0.0
packageVersionTextTH :: FilePath -> Code Q Text Source #
Version of packageVersionTH that returns a Text representation of
PackageVersion at compile-time. Returns "UNKNOWN" if any errors are
encountered.
Examples
>>>$$(packageVersionTextTH "package-version.cabal")"0.1.0.0"
>>>$$(packageVersionTextTH "not-found.cabal")"UNKNOWN"
Since: 0.1.0.0
IO
packageVersionThrowIO :: FilePath -> IO PackageVersion Source #
Version of packageVersionEitherIO that throws an
Exception if any errors are encountered.
Examples
>>>packageVersionThrowIO "package-version.cabal"UnsafePackageVersion {unPackageVersion = [0,1,0,0]}
Since: 0.1.0.0
packageVersionStringIO :: FilePath -> IO String Source #
Version of packageVersionEitherIO that returns a String representation of
PackageVersion at runtime. Returns "UNKNOWN" if any errors are
encountered.
Examples
>>>packageVersionStringIO "package-version.cabal""0.1.0.0"
>>>packageVersionStringIO "not-found.cabal""UNKNOWN"
Since: 0.1.0.0
packageVersionTextIO :: FilePath -> IO Text Source #
Version of packageVersionEitherIO that returns a Text representation of
PackageVersion at runtime. Returns "UNKNOWN" if any errors are
encountered.
Examples
>>>packageVersionTextIO "package-version.cabal""0.1.0.0"
>>>packageVersionTextIO "not-found.cabal""UNKNOWN"
Since: 0.1.0.0
packageVersionEitherIO :: FilePath -> IO (Either ReadFileError PackageVersion) Source #
Reads the cabal-file's version.
Examples
>>>packageVersionEitherIO "package-version.cabal"Right (UnsafePackageVersion {unPackageVersion = [0,1,0,0]})
Since: 0.1.0.0
Errors
data ValidationError Source #
Errors that can occur when validating PVP version numbers.
Since: 0.1.0.0
Constructors
| VTooShortErr [Int] | PVP version numbers must be at least A.B Since: 0.1.0.0 |
| VNegativeErr Int | PVP version numbers cannot be negative. Since: 0.1.0.0 |
Instances
data ReadStringError Source #
Errors that can occur when reading PVP version numbers.
Since: 0.1.0.0
Constructors
| RsReadStrErr String | Error when reading a string. Since: 0.1.0.0 |
| RsValidateErr ValidationError | Validation error. Since: 0.1.0.0 |
Instances
data ReadFileError Source #
Errors that can occur when reading PVP version numbers from a file.
Since: 0.1.0.0
Constructors
| RfFileNotFoundErr String | Error for missing file. Since: 0.1.0.0 |
| RfVersionNotFoundErr FilePath | Error for missing version. Since: 0.1.0.0 |
| RfReadValidateErr ReadStringError | Read/Validation error. Since: 0.1.0.0 |