[Haskell-cafe] The Poor Man's PVP-Checking Tool

Hi, The issue of a tool to help with checking packages against the Package Versioning Policy (PVP: http://www.haskell.org/haskellwiki/Package_versioning_policy) has come up several times on this list, and it seems to be a generally wanted tool. One of the things desired in such a tool is the ability to check what has been added/changed/removed in the latest version of a package, to help see what kind of version bump is needed according to the PVP. This could also be used to check if past releases have obeyed the PVP. A proper way to build this tool is to parse the types of everything involved (functions, data types, and instances), and check them for being the same (given that the type parameters may have been renamed, or a definition substituted for a synonym and so on). I have instead hacked together a tool in an hour or so that roughly does the job. It uses Perl, which I haven't written for a long time, because that was quickest -- if this bothers you, pretend its a crazy Haskell EDSL or something :-). I've attached the Perl script. It combines the command-line tools diff and sort with a tiny bit of manual processing along with the Haskell tool cabal-install, and brings them to bear on the output of "haddock --hoogle", which already nicely spits out the types of all functions, data types and instances in your library. It looks for differences in the output between two package versions, and tells you what version bump it thinks you need. It errs on the conservative side, I believe -- it should never miss a bump when it's needed, but you may sometimes get a false alarm if you've made a harmless change. As an example, let's take the recent stm release. You run the Perl script with the name and version of both package versions (if you omit the version, it should use the latest): ==== neil at beast ~: perl cmp.perl stm-2.1.2.0 stm-2.1.1.2 Warning: The documentation for the following packages are not installed. No links will be generated to these packages: ffi-1.0, rts-1.0 Warning: The documentation for the following packages are not installed. No links will be generated to these packages: ffi-1.0, rts-1.0 25a26 > Control.Concurrent.STM.TVar:readTVarIO :: TVar a -> IO a 39c40 < @version 2.1.1.2 --- > @version 2.1.2.0 Given previous version number A.B.C.D: It seems you have added something. You must increase C (or A or B) ==== For those who can read diff, you get the diff. At the bottom, the tool works out the required bump; here something was added so C must be increased, and we can see that the package did just that. Let's take another example from my latest development version of my CHP library; here I run the command with one argument (chp, which means the latest version on Hackage): ==== neil at banshee ~/work/chp: perl cmp.perl chp Warning: The documentation for the following packages are not installed. No links will be generated to these packages: rts-1.0 Control/Concurrent/CHP/Alt.hs:116:9: Warning: orphan instance: instance Alternative CHP Warning: The documentation for the following packages are not installed. No links will be generated to these packages: rts-1.0 6a7 > Control.Concurrent.CHP.Alt:instance Alternative CHP 82d82 < Control.Concurrent.CHP.Channels.Creation:class ChannelTuple t 88,92d87 < Control.Concurrent.CHP.Channels.Creation:instance (Channel r w) => ChannelTuple (Chan r w a, Chan r w a) < Control.Concurrent.CHP.Channels.Creation:instance (Channel r w) => ChannelTuple (Chan r w a, Chan r w a, Chan r w a) < Control.Concurrent.CHP.Channels.Creation:instance (Channel r w) => ChannelTuple (Chan r w a, Chan r w a, Chan r w a, Chan r w a) < Control.Concurrent.CHP.Channels.Creation:instance (Channel r w) => ChannelTuple (Chan r w a, Chan r w a, Chan r w a, Chan r w a, Chan r w a) < Control.Concurrent.CHP.Channels.Creation:instance (Channel r w) => ChannelTuple (Chan r w a, Chan r w a, Chan r w a, Chan r w a, Chan r w a, Chan r w a) 102d96 < Control.Concurrent.CHP.Channels.Creation:newChannels :: (ChannelTuple t, MonadCHP m) => m t 149c143 < Control.Concurrent.CHP.Monad:class (MonadIO m) => MonadCHP m --- > Control.Concurrent.CHP.Monad:class (Monad m) => MonadCHP m 155a150 > Control.Concurrent.CHP.Monad:foreverP :: CHP a -> CHP b 156a152 > Control.Concurrent.CHP.Monad:liftIO_CHP :: IO a -> CHP a 160a157 > Control.Concurrent.CHP.Monad:process :: String -> a -> a 164a162 > Control.Concurrent.CHP.Monad:subProcess :: String -> a -> a 169c167 < Control.Concurrent.CHP.Parallel:data (Monad m, MonadCHP m) => ForkingT m a --- > Control.Concurrent.CHP.Parallel:data ForkingT m a 173d170 < Control.Concurrent.CHP.Parallel:instance (MonadIO m) => MonadIO (ForkingT m) 175c172 < Control.Concurrent.CHP.Parallel:instance MonadTrans ForkingT --- > Control.Concurrent.CHP.Parallel:liftForking :: (Monad m) => m a -> ForkingT m a 239c236 < @version 2.1.0.1 --- > @version 2.2.0 Given previous version number A.B.C.D: It seems you have added, removed or changed some instances. You must increase A or B It seems you have removed something, or changed its name or type. You must increase A or B It seems you have added something. You must increase C (or A or B) ==== As you can see, I've been changing a lot in CHP, and I'm going to need a major version bump (which I've already put in, as you can see: 2.1.0.1 to 2.2.0). It shouldn't be too hard to augment the tool to check the versions against the required bump. I think that covers everything. The script has been tested with GHC 6.10.4 (and tools of a similar vintage) and 6.12.1 (with near-enough the latest versions of most things), but it will probably go wrong if you sneeze at it. In particular, many newer Haskell features (e.g. GADTs) may throw it off, and I'm not sure if it will work if you use it on an OS that's too far from Linux. But hopefully it'll provide a useful stop-gap for some until a real tool is developed, and I think it's at least better than having nothing. Thanks, Neil. -------------- next part -------------- A non-text attachment was scrubbed... Name: cmp.perl Type: application/x-perl Size: 2019 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-cafe/attachments/20100426/116b44bc/cmp.bin