qualified imports, PVP and so on (Was: add new Data.Bits.Bits(bitZero) method)

Edward Kmett ekmett at gmail.com
Fri Feb 28 20:23:01 UTC 2014


I just want to say thank you for writing this tool.

I may not agree with your interpretation of the PVP on this particular
issue, and will probably only use it on a couple of smaller packages that
have almost no imports, but at least putting code out there to help those
who do want to work in that style is a very helpful and valuable thing.

-Edward


On Fri, Feb 28, 2014 at 3:10 PM, Henning Thielemann <
schlepptop at henning-thielemann.de> wrote:

> I got distracted by writing a tool that checks consistency of package
> dependencies and import styles. It's not yet perfect, but usable:
>
> https://hackage.haskell.org/package/check-pvp
>
>
> Description:
>   Check whether the version ranges used in the @Build-Depends@ field
>   matches the style of module imports
>   according to the Package Versioning Policy (PVP).
>   See <http://www.haskell.org/haskellwiki/Package_versioning_policy>.
>   The tool essentially looks for any dependency
>   like @containers >=0.5 && <0.6@
>   that allows the addition of identifiers to modules
>   within the version range.
>   Then it checks whether all module imports from @containers@
>   are protected against name clashes
>   that could be caused by addition of identifiers.
>   .
>   You must run the tool in a directory containing a Cabal package.
>   .
>   > $ check-pvp
>   .
>   This requires that the package is configured,
>   since only then the association of packages to modules is known.
>   If you want to run the tool on a non-configured package
>   you may just check all imports for addition-proof style.
>   .
>   > $ check-pvp --include-all
>   .
>   It follows a detailed description of the procedure
>   and the rationale behind it.
>   .
>   First the program classifies all dependencies
>   in the Cabal file of the package.
>   You can show all classifications with the @--classify-dependencies at option,
>   otherwise only problematic dependencies are shown.
>   .
>   A dependency like @containers >=0.5.0.3 && <0.5.1@
>   does not allow changes of the API of @containers@
>   and thus the program does not check its imports.
>   Clashing import abbreviations are an exception.
>   .
>   The dependency @containers >=0.5.1 && <0.6@
>   requires more care when importing modules from @containers@
>   and this is what the program is going to check next.
>   This is the main purpose of the program!
>   I warmly recommend this kind of dependency range
>   since it greatly reduces the work
>   to keep your package going together with its imported packages.
>   .
>   Dependencies like @containers >=0.5@ or @containers >=0.5 && <1@
>   are always problematic,
>   since within the specified version ranges identifier can disappear.
>   There is no import style that protects against removed identifiers.
>   .
>   An inclusive upper bound as in @containers >=0.5 && <=0.6@
>   will also cause a warning, because it is unnecessarily strict.
>   If you know that @containers-0.6@ works for you,
>   then @containers-0.6.0.1@ or @containers-0.6.1@ will also work,
>   depending on your import style.
>   A special case of inclusive upper bounds are specific versions
>   like in @containers ==0.6 at .
>   The argument for the warning remains the same.
>   .
>   Please note that the check of ranges
>   is performed entirely on the package description.
>   The program will not inspect the imported module contents.
>   E.g. if you depend on @containers >=0.5 && <0.6@
>   but import in a way that risks name clashes,
>   then you may just extend the dependency to @containers >=0.5 && <0.6.1@
>   in order to let the checker fall silent.
>   If you use the dependency @containers >=0.5 && <0.6.1@
>   then the checker expects that you have verified
>   that your package works with all versions of kind @0.5.x@
>   and the version @0.6.0 at .
>   Other versions would then work, too,
>   due to the constraints imposed by package versioning policy.
>   .
>   Let us now look at imports
>   that must be protected against identifier additions.
>   .
>   The program may complain about a lax import.
>   This means you have imported like
>   .
>   > import Data.Map as Map
>   .
>   Additions to @Data.Map@ may clash with other identifiers,
>   thus you must import either
>   .
>   > import qualified Data.Map as Map
>   .
>   or
>   .
>   > import Data.Map (Map)
>   .
>   The program may complain about an open list of constructors as in
>   .
>   > import Data.Sequence (ViewL(..))
>   .
>   Additions of constructors to @ViewL@ may also conflict with other
> identifiers.
>   You must instead import like
>   .
>   > import Data.Sequence (ViewL(EmptyL, (:<)))
>   .
>   or
>   .
>   > import qualified Data.Sequence as Seq
>   .
>   The program emits an error on clashing module abbreviations like
>   .
>   > import qualified Data.Map.Lazy as Map
>   > import qualified Data.Map.Strict as Map
>   .
>   This error is raised
>   whenever multiple modules are imported with the same abbreviation,
>   where at least one module is open for additions.
>   Our test is overly strict in the sense that it also blames
>   .
>   > import qualified Data.Map as Map
>   > import qualified Data.Map as Map
>   .
>   but I think it is good idea to avoid redundant imports anyway.
>   .
>   Additionally you can enable a test for hiding imports
>   with the @--pedantic@ option.
>   The import
>   .
>   > import Data.Map hiding (insert)
>   .
>   is not bad in the sense of the PVP,
>   but this way you depend on the existence of the identifier @insert@
>   although you do not need it.
>   If it is removed in a later version of @containers@,
>   then your import breaks although you did not use the identifier.
>   .
>   Finally you can control what items are checked.
>   First of all you can select the imports that are checked.
>   Normally the imports are checked that belong to lax dependencies
>   like @containers >=0.5 && <0.6 at .
>   However this requires the package to be configured
>   in order to know which import belongs to which dependency.
>   E.g. @Data.Map@ belongs to @containers at .
>   You can just check all imports for being addition-proof
>   using the @--include-all@ option.
>   Following you can write the options
>   @--include-import@,
>   @--exclude-import@,
>   @--include-dependency@,
>   @--exclude-dependency@
>   that allow to additionally check or ignore imports
>   from certain modules or packages.
>   These modifiers are applied from left to right.
>   E.g. @--exclude-import=Prelude@ will accept any import style for
> @Prelude@
>   and @--exclude-dependency=foobar@ will ignore the package @foobar@,
>   say, because it does not conform to the PVP.
>   .
>   Secondly, you may ignore certain modules or components of the package
>   using the options
>   @--exclude-module@,
>   @--exclude-library@,
>   @--exclude-executables@,
>   @--exclude-testsuites@,
>   @--exclude-benchmarks at .
>   E.g. @--exclude-module=Paths_PKG@ will exclude the Paths module
>   that is generated by Cabal.
>   I assume that it will always be free of name clashes.
>   .
>   Known problems:
>   .
>   * The program cannot automatically filter out the @Paths@ module.
>   .
>   * The program cannot find and check preprocessed modules.
>   .
>   * The program may yield wrong results in the presence of Cabal
> conditions.
>   .
>   If this program proves to be useful
>   it might eventually be integrated in the @check@ command of
> @cabal-install at .
>   See <https://github.com/haskell/cabal/issues/1703>.
>   .
>   Alternative:
>   If you want to allow exclusively large version ranges, i.e. @>=x.y &&
> <x.y+1@,
>   then you may also add the option @-fwarn-missing-import-lists@
>   to the @GHC-Options@ fields of your Cabal file.
>   See <https://ghc.haskell.org/trac/ghc/ticket/4977>.
>   Unfortunately there is no GHC warning on clashing module abbreviations.
>   See <https://ghc.haskell.org/trac/ghc/ticket/4980>.
>
>
> _______________________________________________
> Libraries mailing list
> Libraries at haskell.org
> http://www.haskell.org/mailman/listinfo/libraries
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/libraries/attachments/20140228/98288fb9/attachment.html>


More information about the Libraries mailing list