[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: a new tool fedabipkgdiff



Hello Chenxiong,

Chenxiong Qi <cqi@redhat.com> writes:

> An updated patch with a small fix.

Okay, this is the one I have looked at.  Thanks.

>> This is a new tool fedabipkgdiff that would be much convenient for
>> Fedora packagers to check potential ABI/API differences quickly using
>> abipkgdiff shipped with libabigail. This tool came from a cool idea from
>> Dodji.

[...]

>> For more details, please refer to
>> https://sourceware.org/bugzilla/show_bug.cgi?id=19428

Thank you very much for hacking on this enhancement request.

>> Currently, as the first step, it supports following ways,
>> 
>> fedabipkgdiff --from fc23 ./foo-0.1-1.fc23.x86_64.rpm
>> fedabipkgdiff --from fc23 --to fc24 foo
>> fedabipkgdiff foo-0.1-1.fc23 foo-0.1-1.fc24
>> fedabipkgdiff foo-0.1-1.fc23.i686 foo-0.1-1.fc24.i686

This is really cool.  Seriously.  I have tested the patch and it works
for me :-)

>> Next step is to support the 4th use case mentioned in bug 19428.

Great.

>> fedabipkgdiff is being under development, still need to improve. Welcome
>> any feedback.

I do have some comments, please find them below.

> Subject: [PATCH] new tool of fedabipkgdiff
>
> fedabipkgdiff is a convenient way for Fedora packagers to inspect ABI
> compatibility issues quickly.
>
> Currently with the first version of fedabipkgdiff, you can invoke it in
> following ways.
>
> fedabipkgdiff --from fc23 foo-0.1-1.fc23.x86_64.rpm
> fedabipkgdiff --from fc23 --to fc24 foo
> fedabipkgdiff foo-0.1-1.fc23 foo-0.1-1.fc24
> fedabipkgdiff foo-0.1-1.fc23.i686 foo-0.1-1.fc24.i686
>
> Bug 19428

The commit log of patches must follow a format that is explained in the
source tree.  You can read it online at
https://sourceware.org/git/gitweb.cgi?p=libabigail.git;a=blob_plain;f=COMMIT-LOG-GUIDELINES.

This patch is missing the ChangeLog part in the GNU style format.  I can
add it later for you if you like, as an example :-)

>  .gitignore                    |   3 +
>  tests/Makefile.am             |   4 +
>  tests/runtestfedabipkgdiff.sh |   5 +
>  tools/fedabipkgdiff           | 855 ++++++++++++++++++++++++++++++++++++++++++

I see that the patch is missing some changes necessary to integrate it
to the autotool machinery and have the 'configure' script check for the
dependencies of the fedabipkgdiff tool (mostly all the python modules
and whatnot).  I know this can look dreadful at first sight, so I made
the changes.  I have attached the patch at the end of this message.

After those changes, the output of the configure script (that's related
to my changes looks like):

    checking for wget... /bin/wget
    checking for python... /bin/python
    checking for python version... 2.7.5
    checking python module: argparse... yes
    checking python module: glob... yes
    checking python module: logging... yes
    checking python module: os... yes
    checking python module: re... yes
    checking python module: shlex... yes
    checking python module: subprocess... yes
    checking python module: sys... yes
    checking python module: itertools... yes
    checking python module: urlparse... yes
    checking python module: koji... yes

    [...]

    configure:
    =====================================================================
            Libabigail: 1.0.rc3
    =====================================================================

                    Here is the configuration of the package:

        Prefix                                         : /home/dodji/.local
        Source code location                           : /home/dodji/git/libabigail/fedabipkgdiff
        C Compiler                                     : gcc
        C++ Compiler		                       : g++

     OPTIONAL FEATURES:
        Enable zip archives                            : no
        Use a C++-11 compiler                          : no
        Enable rpm support in abipkgdiff               : yes
        Enable deb support in abipkgdiff               : yes
        Enable GNU tar archive support in abipkgdiff   : yes
        Enable bash completion	                       : auto
        Enable fedabipkgdiff			       : yes
        Generate html apidoc	                       : yes
        Generate html manual	                       : yes

(see how there is now a new line 'Enable fedabipkgdiff	: yes' in the
final report).

For the record, I have put the patch, along with yours into a private
branch named "dodji/fedabipkgdiff" at
https://sourceware.org/git/gitweb.cgi?p=libabigail.git;a=shortlog;h=refs/heads/dodji/fedabipkgdiff.

[...]

I guess you can just incorporate that patch inside your next version,
unless you'd want me to change something.  Please tell me :-)

> diff --git a/tests/Makefile.am b/tests/Makefile.am
> index caf49e6..958995c 100644
> --- a/tests/Makefile.am
> +++ b/tests/Makefile.am
> @@ -31,6 +31,7 @@ runtestlookupsyms		\
>  runtestaltdwarf			\
>  runtestcorediff			\
>  runtestabidiffexit		\
> +runtestfedabipkgdiff.sh		\
>  $(CXX11_TESTS)

[...]

> diff --git a/tests/runtestfedabipkgdiff.sh b/tests/runtestfedabipkgdiff.sh
> new file mode 100755
> index 0000000..4144419
> --- /dev/null
> +++ b/tests/runtestfedabipkgdiff.sh
> @@ -0,0 +1,5 @@
> +#!/usr/bin/bash
> +
> +export FEDABIPKGDIFF_TESTS=1
> +
> +../../tools/fedabipkgdiff
> \ No newline at end of file

Actually, I think the runtestfedabipkgdiff.sh could be a proper python
script that contains the actual unit tests of fedabipkgdiff, rather than
having the unit tests be in the fedabipkgdiff file itself.

That file would then load (using the imp.load_source() function from the
python standard library) by specifying the path to the the fedabipkgdiff
from the source, so that "make check" uses the fedabipkgdiff from the
sources and not the one that might already be installed on the
system. There is a potentially a little bit of autoconf magic to do
here, but I can help you here for the details.

[...]

> diff --git a/tools/fedabipkgdiff b/tools/fedabipkgdiff
> new file mode 100755
> index 0000000..5d62db2
> --- /dev/null
> +++ b/tools/fedabipkgdiff
> @@ -0,0 +1,855 @@
> +#!/usr/bin/env python
> +# -*- coding: utf-8 -*-
> +
> +import argparse
> +import glob
p> +import logging
> +import os
> +import re
> +import shlex
> +import subprocess
> +import sys
> +
> +from itertools import groupby
> +from urlparse import urlparse
> +
> +import koji
> +
> +"""
> +Find proper RPM packages from koji to run abipkgdiff.
> +
> +Internal structure is
> +
> +fc23                                  fc24
> +i686                                  i686
> +    foo-0.1-1.fc23.i686.rpm               foo-0.2-1.fc24.i686.rpm
> +    foo-debuginfo-0.1-1.fc23.i686.rpm     foo-debuginfo-0.2-1.fc23.i686.rpm
> +x86_64                                x86_64
> +    foo-0.1-1.fc23.x86_64.rpm             foo-0.2-1.fc24.x86_64.rpm
> +    foo-debuginfo-0.1-1.fc23.x86_64.rpm
> foo-debuginfo-0.2-1.fc23.x86_64.rpm

This is the 'internal structure' of what exactly? I guess it's the
structure of the cache where the packages are put after they are
downloaded.  It'd be cool to be explicit here and give more details so
that readers won't have to guess.

[...]

OK, I am skipping some details.  I think we'll have more opportunity to
refine them later :-) For now, I am focusing on things that I believe
belong to the big picture.

> +class Brew(object):
> +    """Proxy to kojihub XMLRPC with additional extensions to fedabipkgdiff"""

It looks like the kojihub XMLRPC API is not that well documented, or is
it?  Maybe you could provide a link in the comments about where the APIs
are documented.

> +
> +    def __init__(self, baseurl):
> +        self.session = koji.ClientSession(baseurl)
> +
> +    def listRPMs(self, **kwargs):

It'd be nice to detail the exact set of parameters expected here, their
type, and their meaning, even if those are supposed to be
declared/defined in the Kojihub API.  As that API is not defined here,
it's important that we write down what we think we expect.  I think we
ought to do that generally for all functions, especially those that
expect variable arguments or worse, keyword arguments like this.  It's
important that readers knows what the function expects.

[...]

> +if 'FEDABIPKGDIFF_TESTS' not in os.environ and invoked_from_cmd:
> +    try:
> +        sys.exit(main())
> +    except Exception as e:
> +        print >>sys.stderr, str(e)
> +        sys.exit(1)
> +
> +
> +import itertools
> +import shutil
> +import unittest
> +

As I was saying, earlier, I think this part should be split out from
this file and put in the separate regression test file under tests/.

Hmhm, I guess I should add these to the set of pre-requisite modules
checked by the configure script too ...

Other than that, I think this is an excellent start.  This thing is
really cool.  Thank you thank you thank you for tackling this.  I find
this *super cool*.  Not having to download the packages for which we
want to compare the ABI? this is pure magic ...  I am so thrilled :-)

> Happy Hacking

Indeed, I am so happy right now :-)

Thanks!

>From 35bbdc075b95c69b9e801f9f45ff4d5b14ebbad1 Mon Sep 17 00:00:00 2001
From: Dodji Seketeli <dodji@redhat.com>
Date: Fri, 19 Feb 2016 17:38:16 +0100
Subject: [PATCH 2/2] Add autotooling to fedabipkgdiff

This patch adds detection for the dependencies of fedabipkgdiff.  To
do that I had to use some extra autoconf macros from the GNU Autoconf
Archive at http://www.gnu.org/software/autoconf-archive.  I got the
macros from the tarball of the autoconf-archive at
http://mirror0.babylon.network/gnu/autoconf-archive/autoconf-archive-2015.09.25.tar.xz.

Basically, the patch adds a new --enable-fedabipkgdiff option to the
configure program.  By default the value of that option is "auto".
In that "auto" mode, the configure program checks for the dependencies
of fedabipkgdiff.  If they are present then the tool will be installed
by 'make install'.  If they are not, then the tool will just be
disabled and 'make install' won't install it.

If --enable-fedabipkgdiff is explicitly provided, then it's value is
set to 'yes'.  In that mode, the configure program checks for the
dependencies of fedabipkgdiff too.  If any of the dependencies is not
found on the system, the configure program fails and requires the
users to install the missing dependency.

The patch augments the report that is emitted at the end of the
configure script, and make it show the status of the "fedabipkgdiff"
feature; that is, it says if fedabipkgdiff is enabled or not.

The patch also ensures that the new fedabipkgdiff is included to the
source distribution that is built by the standard "make dist" command.

	* autoconf-archive/ax_compare_version.m4: New file copied from the
	autoconf-archive project.
	* autoconf-archive/ax_prog_python_version.m4: Likewise.
	* autoconf-archive/ax_python_module.m4: Likewise.
	* Makefile.am: Add the new files above to the source distribution.
	* configure.ac: Include the new m4 macros from the autoconf
	archive. Add a new --enable-fedabipkgdiff option. Update the
	report at the end of the configure process to show the status of
	the fedabipkgdiff feature.
	* tools/Makefile.am: Include the fedabipkgdiff to the source
	distribution and install it if the "fedabipkgdiff" feature is
	enabled.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
---
 Makefile.am                                |   3 +
 autoconf-archive/ax_compare_version.m4     | 177 +++++++++++++++++++++++++++++
 autoconf-archive/ax_prog_python_version.m4 |  66 +++++++++++
 autoconf-archive/ax_python_module.m4       |  56 +++++++++
 configure.ac                               |  77 +++++++++++++
 tools/Makefile.am                          |   6 +
 6 files changed, 385 insertions(+)
 create mode 100644 autoconf-archive/ax_compare_version.m4
 create mode 100644 autoconf-archive/ax_prog_python_version.m4
 create mode 100644 autoconf-archive/ax_python_module.m4

diff --git a/Makefile.am b/Makefile.am
index c855cf6..1ae2290 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -12,6 +12,9 @@ pkgconfig_DATA = libabigail.pc
 #dist_bashcompletion_DATA =
 
 EXTRA_DIST = 			\
+autoconf-archive/ax_python_module.m4 \
+autoconf-archive/ax_prog_python_version.m4 \
+autoconf-archive/ax_compare_version.m4 \
 NEWS README COPYING ChangeLog	\
 COPYING-LGPLV2 COPYING-LGPLV3	\
 COPYING-GPLV3 gen-changelog.py	\
diff --git a/autoconf-archive/ax_compare_version.m4 b/autoconf-archive/ax_compare_version.m4
new file mode 100644
index 0000000..74dc0fd
--- /dev/null
+++ b/autoconf-archive/ax_compare_version.m4
@@ -0,0 +1,177 @@
+# ===========================================================================
+#    http://www.gnu.org/software/autoconf-archive/ax_compare_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_COMPARE_VERSION(VERSION_A, OP, VERSION_B, [ACTION-IF-TRUE], [ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+#   This macro compares two version strings. Due to the various number of
+#   minor-version numbers that can exist, and the fact that string
+#   comparisons are not compatible with numeric comparisons, this is not
+#   necessarily trivial to do in a autoconf script. This macro makes doing
+#   these comparisons easy.
+#
+#   The six basic comparisons are available, as well as checking equality
+#   limited to a certain number of minor-version levels.
+#
+#   The operator OP determines what type of comparison to do, and can be one
+#   of:
+#
+#    eq  - equal (test A == B)
+#    ne  - not equal (test A != B)
+#    le  - less than or equal (test A <= B)
+#    ge  - greater than or equal (test A >= B)
+#    lt  - less than (test A < B)
+#    gt  - greater than (test A > B)
+#
+#   Additionally, the eq and ne operator can have a number after it to limit
+#   the test to that number of minor versions.
+#
+#    eq0 - equal up to the length of the shorter version
+#    ne0 - not equal up to the length of the shorter version
+#    eqN - equal up to N sub-version levels
+#    neN - not equal up to N sub-version levels
+#
+#   When the condition is true, shell commands ACTION-IF-TRUE are run,
+#   otherwise shell commands ACTION-IF-FALSE are run. The environment
+#   variable 'ax_compare_version' is always set to either 'true' or 'false'
+#   as well.
+#
+#   Examples:
+#
+#     AX_COMPARE_VERSION([3.15.7],[lt],[3.15.8])
+#     AX_COMPARE_VERSION([3.15],[lt],[3.15.8])
+#
+#   would both be true.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq],[3.15.8])
+#     AX_COMPARE_VERSION([3.15],[gt],[3.15.8])
+#
+#   would both be false.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq2],[3.15.8])
+#
+#   would be true because it is only comparing two minor versions.
+#
+#     AX_COMPARE_VERSION([3.15.7],[eq0],[3.15])
+#
+#   would be true because it is only comparing the lesser number of minor
+#   versions of the two values.
+#
+#   Note: The characters that separate the version numbers do not matter. An
+#   empty string is the same as version 0. OP is evaluated by autoconf, not
+#   configure, so must be a string, not a variable.
+#
+#   The author would like to acknowledge Guido Draheim whose advice about
+#   the m4_case and m4_ifvaln functions make this macro only include the
+#   portions necessary to perform the specific comparison specified by the
+#   OP argument in the final configure script.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Tim Toolan <toolan@ele.uri.edu>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 11
+
+dnl #########################################################################
+AC_DEFUN([AX_COMPARE_VERSION], [
+  AC_REQUIRE([AC_PROG_AWK])
+
+  # Used to indicate true or false condition
+  ax_compare_version=false
+
+  # Convert the two version strings to be compared into a format that
+  # allows a simple string comparison.  The end result is that a version
+  # string of the form 1.12.5-r617 will be converted to the form
+  # 0001001200050617.  In other words, each number is zero padded to four
+  # digits, and non digits are removed.
+  AS_VAR_PUSHDEF([A],[ax_compare_version_A])
+  A=`echo "$1" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+                     -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/[[^0-9]]//g'`
+
+  AS_VAR_PUSHDEF([B],[ax_compare_version_B])
+  B=`echo "$3" | sed -e 's/\([[0-9]]*\)/Z\1Z/g' \
+                     -e 's/Z\([[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/Z\([[0-9]][[0-9]][[0-9]]\)Z/Z0\1Z/g' \
+                     -e 's/[[^0-9]]//g'`
+
+  dnl # In the case of le, ge, lt, and gt, the strings are sorted as necessary
+  dnl # then the first line is used to determine if the condition is true.
+  dnl # The sed right after the echo is to remove any indented white space.
+  m4_case(m4_tolower($2),
+  [lt],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+  ],
+  [gt],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/false/;s/x${B}/true/;1q"`
+  ],
+  [le],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+  ],
+  [ge],[
+    ax_compare_version=`echo "x$A
+x$B" | sed 's/^ *//' | sort -r | sed "s/x${A}/true/;s/x${B}/false/;1q"`
+  ],[
+    dnl Split the operator from the subversion count if present.
+    m4_bmatch(m4_substr($2,2),
+    [0],[
+      # A count of zero means use the length of the shorter version.
+      # Determine the number of characters in A and B.
+      ax_compare_version_len_A=`echo "$A" | $AWK '{print(length)}'`
+      ax_compare_version_len_B=`echo "$B" | $AWK '{print(length)}'`
+
+      # Set A to no more than B's length and B to no more than A's length.
+      A=`echo "$A" | sed "s/\(.\{$ax_compare_version_len_B\}\).*/\1/"`
+      B=`echo "$B" | sed "s/\(.\{$ax_compare_version_len_A\}\).*/\1/"`
+    ],
+    [[0-9]+],[
+      # A count greater than zero means use only that many subversions
+      A=`echo "$A" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+      B=`echo "$B" | sed "s/\(\([[0-9]]\{4\}\)\{m4_substr($2,2)\}\).*/\1/"`
+    ],
+    [.+],[
+      AC_WARNING(
+        [illegal OP numeric parameter: $2])
+    ],[])
+
+    # Pad zeros at end of numbers to make same length.
+    ax_compare_version_tmp_A="$A`echo $B | sed 's/./0/g'`"
+    B="$B`echo $A | sed 's/./0/g'`"
+    A="$ax_compare_version_tmp_A"
+
+    # Check for equality or inequality as necessary.
+    m4_case(m4_tolower(m4_substr($2,0,2)),
+    [eq],[
+      test "x$A" = "x$B" && ax_compare_version=true
+    ],
+    [ne],[
+      test "x$A" != "x$B" && ax_compare_version=true
+    ],[
+      AC_WARNING([illegal OP parameter: $2])
+    ])
+  ])
+
+  AS_VAR_POPDEF([A])dnl
+  AS_VAR_POPDEF([B])dnl
+
+  dnl # Execute ACTION-IF-TRUE / ACTION-IF-FALSE.
+  if test "$ax_compare_version" = "true" ; then
+    m4_ifvaln([$4],[$4],[:])dnl
+    m4_ifvaln([$5],[else $5])dnl
+  fi
+]) dnl AX_COMPARE_VERSION
diff --git a/autoconf-archive/ax_prog_python_version.m4 b/autoconf-archive/ax_prog_python_version.m4
new file mode 100644
index 0000000..628a3e4
--- /dev/null
+++ b/autoconf-archive/ax_prog_python_version.m4
@@ -0,0 +1,66 @@
+# ===========================================================================
+#  http://www.gnu.org/software/autoconf-archive/ax_prog_python_version.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PROG_PYTHON_VERSION([VERSION],[ACTION-IF-TRUE],[ACTION-IF-FALSE])
+#
+# DESCRIPTION
+#
+#   Makes sure that python supports the version indicated. If true the shell
+#   commands in ACTION-IF-TRUE are executed. If not the shell commands in
+#   ACTION-IF-FALSE are run. Note if $PYTHON is not set (for example by
+#   running AC_CHECK_PROG or AC_PATH_PROG) the macro will fail.
+#
+#   Example:
+#
+#     AC_PATH_PROG([PYTHON],[python])
+#     AX_PROG_PYTHON_VERSION([2.4.4],[ ... ],[ ... ])
+#
+#   This will check to make sure that the python you have supports at least
+#   version 2.4.4.
+#
+#   NOTE: This macro uses the $PYTHON variable to perform the check.
+#   AX_WITH_PYTHON can be used to set that variable prior to running this
+#   macro. The $PYTHON_VERSION variable will be valorized with the detected
+#   version.
+#
+# LICENSE
+#
+#   Copyright (c) 2009 Francesco Salvestrini <salvestrini@users.sourceforge.net>
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 11
+
+AC_DEFUN([AX_PROG_PYTHON_VERSION],[
+    AC_REQUIRE([AC_PROG_SED])
+    AC_REQUIRE([AC_PROG_GREP])
+
+    AS_IF([test -n "$PYTHON"],[
+        ax_python_version="$1"
+
+        AC_MSG_CHECKING([for python version])
+        changequote(<<,>>)
+        python_version=`$PYTHON -V 2>&1 | $GREP "^Python " | $SED -e 's/^.* \([0-9]*\.[0-9]*\.[0-9]*\)/\1/'`
+        changequote([,])
+        AC_MSG_RESULT($python_version)
+
+	AC_SUBST([PYTHON_VERSION],[$python_version])
+
+        AX_COMPARE_VERSION([$ax_python_version],[le],[$python_version],[
+	    :
+            $2
+        ],[
+	    :
+            $3
+        ])
+    ],[
+        AC_MSG_WARN([could not find the python interpreter])
+        $3
+    ])
+])
diff --git a/autoconf-archive/ax_python_module.m4 b/autoconf-archive/ax_python_module.m4
new file mode 100644
index 0000000..f182c48
--- /dev/null
+++ b/autoconf-archive/ax_python_module.m4
@@ -0,0 +1,56 @@
+# ===========================================================================
+#     http://www.gnu.org/software/autoconf-archive/ax_python_module.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+#   AX_PYTHON_MODULE(modname[, fatal, python])
+#
+# DESCRIPTION
+#
+#   Checks for Python module.
+#
+#   If fatal is non-empty then absence of a module will trigger an error.
+#   The third parameter can either be "python" for Python 2 or "python3" for
+#   Python 3; defaults to Python 3.
+#
+# LICENSE
+#
+#   Copyright (c) 2008 Andrew Collier
+#
+#   Copying and distribution of this file, with or without modification, are
+#   permitted in any medium without royalty provided the copyright notice
+#   and this notice are preserved. This file is offered as-is, without any
+#   warranty.
+
+#serial 8
+
+AU_ALIAS([AC_PYTHON_MODULE], [AX_PYTHON_MODULE])
+AC_DEFUN([AX_PYTHON_MODULE],[
+    if test -z $PYTHON;
+    then
+        if test -z "$3";
+        then
+            PYTHON="python3"
+        else
+            PYTHON="$3"
+        fi
+    fi
+    PYTHON_NAME=`basename $PYTHON`
+    AC_MSG_CHECKING($PYTHON_NAME module: $1)
+    $PYTHON -c "import $1" 2>/dev/null
+    if test $? -eq 0;
+    then
+        AC_MSG_RESULT(yes)
+        eval AS_TR_CPP(HAVE_PYMOD_$1)=yes
+    else
+        AC_MSG_RESULT(no)
+        eval AS_TR_CPP(HAVE_PYMOD_$1)=no
+        #
+        if test -n "$2"
+        then
+            AC_MSG_ERROR(failed to find required module $1)
+            exit 1
+        fi
+    fi
+])
diff --git a/configure.ac b/configure.ac
index f7efca5..687a2ca 100644
--- a/configure.ac
+++ b/configure.ac
@@ -14,6 +14,18 @@ AC_CONFIG_HEADER([config.h])
 AC_CONFIG_SRCDIR([README])
 AC_CONFIG_MACRO_DIR([m4])
 
+dnl Include some autoconf macros to check for python modules.
+dnl
+dnl These macros are coming from the autoconf archive at
+dnl http://www.gnu.org/software/autoconf-archive
+
+dnl This one is for the AX_PYTHON_MODULE() macro.
+m4_include([autoconf-archive/ax_python_module.m4])
+
+dnl These two below are for the AX_PROG_PYTHON_VERSION() module.
+m4_include([autoconf-archive/ax_compare_version.m4])
+m4_include([autoconf-archive/ax_prog_python_version.m4])
+
 AM_INIT_AUTOMAKE([1.11.1 foreign subdir-objects tar-ustar parallel-tests])
 AM_MAINTAINER_MODE([enable])
 
@@ -76,6 +88,12 @@ AC_ARG_ENABLE([bash-completion],
 	      ENABLE_BASH_COMPLETION=$enableval,
 	      ENABLE_BASH_COMPLETION=auto)
 
+AC_ARG_ENABLE([fedabipkgdiff],
+	      AS_HELP_STRING([--enable-fedabipkgdiff=yes|no|auto],
+			     [enable the fedabipkgdiff tool]),
+	      ENABLE_FEDABIPKGDIFF=$enableval,
+	      ENABLE_FEDABIPKGDIFF=auto)
+
 dnl *************************************************
 dnl check for dependencies
 dnl *************************************************
@@ -219,6 +237,64 @@ fi
 
 AM_CONDITIONAL(ENABLE_BASH_COMPLETION, test x$ENABLE_BASH_COMPLETION = xyes)
 
+dnl if --enable-fedabipkgdiff has the 'auto' value, then check for the required
+dnl python modules.  If they are present, then enable the fedabipkgdiff program.
+dnl If they are not then disable the program.
+dnl
+dnl If --enable-fedabipkgdiff has the 'yes' value, then check for the required
+dnl python modules and whatever dependency fedabipkgdiff needs.  If they are
+dnl not present then the configure script will error out.
+
+if test x$ENABLE_FEDABIPKGDIFF = xauto -o x$ENABLE_FEDABIPKGDIFF = xyes; then
+   CHECK_DEPS_FOR_FEDABIPKGDIFF=yes
+else
+   CHECK_DEPS_FOR_FEDABIPKGDIFF=no
+fi
+
+if test x$CHECK_DEPS_FOR_FEDABIPKGDIFF = xyes; then
+  if test x$ENABLE_FEDABIPKGDIFF = xyes; then
+     FATAL=yes
+  fi
+
+  AC_PATH_PROG(WGET, wget, no)
+
+  if test x$WGET = x$no; then
+    AC_MSG_ERROR(could not find the wget program)
+  fi
+
+  # The minimal python version we want to support is 2.6.6 because EL6
+  # distributions have that version installed.
+  MINIMAL_PYTHON_VERSION="2.6.6"
+
+  AC_PATH_PROG(PYTHON, python, no)
+  AX_PROG_PYTHON_VERSION($MINIMAL_PYTHON_VERSION,
+			 [MINIMAL_PYTHON_VERSION_FOUND=yes],
+			 [MINIMAL_PYTHON_VERSION_FOUND=no])
+
+  if test x$MINIMAL_PYTHON_VERSION_FOUND = xno; then
+    AC_MSG_ERROR([could not find a python program of version at least $MINIMAL_PYTHON_VERSION])
+  fi
+
+  AX_PYTHON_MODULE(argparse, $FATAL, python2)
+  AX_PYTHON_MODULE(glob, $FATAL, python2)
+  AX_PYTHON_MODULE(logging, $FATAL, python2)
+  AX_PYTHON_MODULE(os, $FATAL, python2)
+  AX_PYTHON_MODULE(re, $FATAL, python2)
+  AX_PYTHON_MODULE(shlex, $FATAL, python2)
+  AX_PYTHON_MODULE(subprocess, $FATAL, python2)
+  AX_PYTHON_MODULE(sys, $FATAL, python2)
+  AX_PYTHON_MODULE(itertools, $FATAL, python2)
+  AX_PYTHON_MODULE(urlparse, $FATAL, python2)
+  AX_PYTHON_MODULE(koji, $FATAL, python2)
+  ENABLE_FEDABIPKGDIFF=yes
+
+  if test x$ENABLE_FEDABIPKGDIFF != xyes; then
+    ENABLE_FEDABIPKGDIFF=no
+  fi
+fi
+
+AM_CONDITIONAL(ENABLE_FEDABIPKGDIFF, test x$ENABLE_FEDABIPKGDIFF = xyes)
+
 dnl Check for dependency: libzip
 LIBZIP_VERSION=0.10.1
 
@@ -384,6 +460,7 @@ AC_MSG_NOTICE([
     Enable deb support in abipkgdiff               : ${ENABLE_DEB}
     Enable GNU tar archive support in abipkgdiff   : ${ENABLE_TAR}
     Enable bash completion	                   : ${ENABLE_BASH_COMPLETION}
+    Enable fedabipkgdiff			   : ${ENABLE_FEDABIPKGDIFF}
     Generate html apidoc	                   : ${ENABLE_APIDOC}
     Generate html manual	                   : ${ENABLE_MANUAL}
 ])
diff --git a/tools/Makefile.am b/tools/Makefile.am
index 6125842..6ab5aae 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -6,6 +6,12 @@ else
   bin_PROGRAMS = abidiff abilint abidw abicompat abipkgdiff
 endif
 
+if ENABLE_FEDABIPKGDIFF
+  bin_SCRIPTS = fedabipkgdiff
+else
+  noinst_SCRIPTS = fedabipkgdiff
+endif
+
 noinst_PROGRAMS = abisym abinilint
 
 if ENABLE_ZIP_ARCHIVE
-- 
1.8.3.1

-- 
		Dodji