-
Notifications
You must be signed in to change notification settings - Fork 5
Updating Ports
Remember to integrate with the Ports Collection before attempting to do updates to the ports in the development repository. The integration step should be done anyway, but it could be much more tedious to do after the ports have been updated.
Once it is done, have the "Haskell Porter" tool (see the hsporter
repository) ready and working. In order to do so, clone all the required repositories (note that the ports
repository may be already present, everything is described from scratch here).
$ git clone http://github.com/freebsd-haskell/hsporter
$ git clone http://github.com/freebsd-haskell/ports
Despite its name, the hsporter
repository accommodates two tools:
-
hsporter
, which is a standalone command-line tool for creating and adding newhs-
ports. See the corresponding page for more information on how to use it. -
hsupdater
, which is to update the ports. It can be run either as an non-interactive standalone tool from the command line or as an interactive tool from GHCi. Running from GHCi is recommended and detailed below.
Before launching hsupdater
in GHCi, it has to be configured by creating a hsupdater.conf
file. The skeleton of this file should be already present as hsporter/hsupdater.conf.sample
, so it could be just used as a template.
Most of the configurable settings (such as dbdir
for the temporary package description database, threads
for setting the number of concurrent download threads, or updatesdir
for storing the updated version of the ports) are just fine. That is, only portsdir
should be modified. So, replace root_of_freebsd-haskell_tree
with the actual path of the ports
clone.
$ cd hsporter
$ cat hsupdater.conf.sample | sed 's|root_of_freebsd-haskell_tree|../ports|' > hsupdater.conf
Create the updates
and db
directories, hsupdater
may use them later.
$ mkdir db updates
After everything is set, use GHCi to launch hsupdater
. GHCi itself already implements a "shell-like" interface, so the interactive part of hsupdater
is simply just a pack of Haskell functions that may be invoked from there.
$ ghci src-hsupdater/Main.hs
All the available commands start with the cmd
prefix, so it is enough to type cmd
and then press the Tab key to see a list of them. (The λ?
symbol here presents the GHCi prompt.)
λ? cmd<TAB>
cmdDownloadUpdates cmdPrintUpdateLogs
cmdFetchCabal cmdPrintUpdates
cmdFetchLatestCabal cmdPruneBy
cmdGetLatestHackageVersions cmdShowPruneableBy
cmdIsVersionAllowed cmdUpdatePortVersions
cmdPrintCabalVersions
The commands themselves do not offer much help, rather their names and their types are trying to document what they are up to. (Well, they are in Haskell, why do not use it for our advantage? :-)) For example, check the type of the UpdatePortVersions
command.
λ? :type cmdUpdatePortVersions
cmdUpdatePortVersions :: IO ()
This is IO ()
, which means it is free to call it right away in the GHCi. All the commands are "IO actions" in the Haskell terminology, an such IO actions may be evaluated inside the GHCi directly.
So, first, cache the port versions with this command. This will create a portversions
file that contains the current versions of the ports in the configured tree. The command may be invoked any time later when the ports in tree change.
λ? cmdUpdatePortVersions
Next, the db
directory has to be populated with the latest version of Cabal package descriptions for each of the ported packages.
λ? cmdGetLatestHackageVersions
Initializing...
Fetching new versions...
Fetched: ALUT-2.3.0.1
Fetched: BNFC-2.6.0.3
[...]
After the package database has been built up, there is a command for finding out which packages have new versions available.
λ? cmdPrintUpdates
This command will give a list of all potentially outdated ports and show if moving to their currently known future version may be safe or not. Based on this, the list items may have different variations:
-
"Safe" updates. Nothing special has to be done, everything is fine.
Boolean (devel) 0.2 ---> 0.2.1
That is, the
devel/hs-Boolean
port is at version0.2
, but it could be safely updated to0.2.1
. -
"Unsafe" updates. Some of the port cannot be reliably moved to a newer version. They may be tagged by
U
(forunsatisfied
) orR
(forrestricts
).base64-conduit (devel) 1.0.0 -/-> 1.0.0.1 (U: conduit)
The
devel/hs-base64-conduit
port is at version1.0.0
and version1.0.0.1
is available, but it is not recommended to update, because the latest known version ofconduit
is not supported bybase64-conduit
.Similarly, the latest known version of
conduit
is not recommended as it restricts the update ofbase64-conduit
.conduit (devel) 1.0.11.1 -/-> 1.1.0.2 (R: base64-conduit)
Hence the update of conduit
is considered "unsafe" because the currently available version of base64-conduit
wants conduit
of version greater than (or equal to) 1.0
but lesser than 1.1
. (This restriction is encoded in the corresponding package description.)
There are multiple solutions to this problem.
-
Do not care about the conflicts, but patch the package descriptions in the port, therefore force that version of the package to be used. This may work in some cases, as certain packages can work with dependencies not satisfying the version requirements strictly. If the port has been already patched to work like this, the same strategy may be maintained for the later updates.
-
Try finding a future version that satisfy the version requirements manually.
λ? cmdPrintCabalVersions "conduit" [...] 1.0.17.1, [...] 1.1.0, 1.1.0.1, 1.1.0.2
The
PrintCabalVersions
can print all the past and future versions for the given Cabal package, so an appropriate version may be selected. In the example,1.0.17.1
appears to be a right version forconduit
. TheFetchCabal
command may be used to step back to that version instead.λ? cmdFetchCabal "conduit" "1.0.17.1" Fetching conduit-1.0.17.1...done.
Now updating
base64-conduit
becomes safe.base64-conduit (devel) 1.0.0 ---> 1.0.0.1
-
Try finding a configuration of versions without conflicts with the aid of the tool. The
ShowPruneableBy
and thePruneBy
commands can respectively show and prune the updates along the version restrictions automatically.λ? cmdShowPruneableBy allPruneableUpdates [...] conduit-1.0.11.1 [...] λ? cmdPruneBy allPruneableUpdates Initializing... [...] Pruned: conduit-1.0.11.1 [...]
This may be repeated multiple times in order to reach a configuration where there are no update conflicts at all. Note that the final configuration may not contain any updates as a potential result. Thus the automatic pruning of updates gives a more or the less reliable but also a very conservative recommendation on how to update the ports.
-
Experiment with finding the latest and greatest but non-conflicting updates, with some automated help. In this case, the
PruneBy
command should be used with thepruneableFor
function instead. There, a package and its version should be specified and the tool prunes the versions of all the dependencies. This is especially handy for ports with a numerous dependencies.For example, the updates for the latest version of
yesod-platform
can be ironed out in a single moment.λ? cmdPruneBy (pruneableFor "yesod-platform" "1.2.10")
Once the future port versions have been set, hsporter
could be used to download the updated versions and generate the corresponding FreeBSD port files for them.
λ? cmdDownloadUpdates
Update starts.
Downloaded: base64-conduit (devel) (1.0.0 -> 1.0.0.1)
[...]
Update finished.
The resulting files are placed to the updates
directory, configured earlier. Note that they are not ready to be used directly, although they could be used for doing the updates, as it will be shown below. The GHCi session is over for now, let us quit.
λ? :quit
cd ..
As the next step, the updates shall be merged back to the development repository. For doing so, the merge-trees-sdiff.sh
script can be used from the hsmtk
repository.
$ git clone http://github.com/freebsd-haskell/hsmtk
Note that this script can be also useful for integrating with the Ports Collection. Actually, a similar action is needed, but the direction is the reverse this time. That is why the PORTSDIR
environment variable has to be set accordingly.
$ cd ports
$ env PORTSDIR=../hsporter/updates sh ../hsmtk/merge-trees-sdiff.sh
Be careful with the merges, though. The hsporter
tool will not always be able to provide complete conversion of Cabal packages, some reviewing and manual post-processing is often recommended. But the combination of these two tools can greatly reduce the complexity of the updates.
After the updates have been merged into the ports tree, use git
to commit each of the ports updates individually. This is highly recommended in order to keep the log clear. Thanks to git
, the updates will be atomic as result of pushing anyway.
Before committing, it is recommended to check if the distinfo
and the dependencies are correct, together with checking the changes to be committed.
# make checksum -C devel/hs-base64-conduit
$ git diff devel/hs-base64-conduit
If everything looks all right, commit the changes.
$ git commit -m "devel/hs-base64-conduit: 1.0.0 --> 1.0.0.1" devel/hs-base64-conduit
Although, note that, with the help of hsupdater
, the commit logs could be conveniently generated from the list of updates. They could be then copied and pasted to the command line when committing the updates with git
.
λ? cmdPrintUpdateLogs
devel/hs-base64-conduit: 1.0.0 --> 1.0.0.1
[...]