diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,3 +1,16 @@
+## 0.2.1
+
+* Add BDCS.Export.export, which is the bulk of the "bdcs export" command
+  but in function form.
+* Add BDCS.Exports.Utils.supportedOutputs, which returns a list of supported
+  output formats.
+* Ignore Enhances, Suggests, Recommends, and Supplements weak requirements
+  during dependency solving.
+* Many test-related updates.
+* Allow building with conduit-extra-1.2.
+* Many docker-related build updates.
+* Support building with cabal-2.0.
+
 ## 0.2.0
 
 * Add a module for building virtual filesystem trees.
diff --git a/Dockerfile b/Dockerfile
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,7 +3,7 @@
 COPY entrypoint.sh /usr/local/bin/entrypoint.sh
 ENTRYPOINT ["/usr/local/bin/entrypoint.sh"]
 
-COPY bdcs /usr/local/bin
-COPY bdcs-import /usr/local/libexec/weldr/
-COPY bdcs-export /usr/local/libexec/weldr/
+COPY dist/build/bdcs/bdcs /usr/local/bin
+COPY dist/build/bdcs-import/bdcs-import /usr/local/libexec/weldr/
+COPY dist/build/bdcs-export/bdcs-export /usr/local/libexec/weldr/
 COPY schema.sql /root/schema.sql
diff --git a/Dockerfile.build b/Dockerfile.build
--- a/Dockerfile.build
+++ b/Dockerfile.build
@@ -1,32 +1,16 @@
 FROM welder/fedora:latest
 
 # workaround for https://github.com/bos/math-functions/issues/52
-RUN dnf -y install cabal-install \
+RUN dnf -y install cabal-install wget diffutils beakerlib \
     https://kojipkgs.fedoraproject.org//packages/ghc-vector-th-unbox/0.2.1.6/1.fc26/x86_64/ghc-vector-th-unbox-0.2.1.6-1.fc26.x86_64.rpm \
     https://kojipkgs.fedoraproject.org//packages/ghc-vector-th-unbox/0.2.1.6/1.fc26/x86_64/ghc-vector-th-unbox-devel-0.2.1.6-1.fc26.x86_64.rpm && \
     dnf clean all
 
 ENV PATH /root/.cabal/bin:$PATH
 
-RUN cabal update
-RUN cabal install happy
-RUN cabal install hlint
-
-RUN mkdir /bdcs
-
-# install the build dependencies first so we can cache this layer
-COPY bdcs.cabal /bdcs/
-RUN cd /bdcs/ && cabal update && cabal install --dependencies-only --enable-tests --force-reinstall
-
-# copy the rest of the code and build the application
-COPY cabal.config LICENSE Setup.hs .hlint.yaml /bdcs/
-COPY data/ /bdcs/data/
-COPY src/ /bdcs/src/
-COPY tests/ /bdcs/tests/
-
+# source is already bind-mounted here
 WORKDIR /bdcs/
-RUN hlint .
-RUN cabal configure --enable-tests --enable-coverage --prefix=/usr/local && \
-    cabal build && \
-    cabal test --show-details=always && \
-    cabal install --prefix=/usr/local
+
+# build the application and execute integration tests
+# when the container is started
+ENTRYPOINT ["/bdcs/entrypoint-integration-test.sh"]
diff --git a/Dockerfile.integration-test b/Dockerfile.integration-test
deleted file mode 100644
--- a/Dockerfile.integration-test
+++ /dev/null
@@ -1,8 +0,0 @@
-FROM welder/bdcs-build-img:latest
-MAINTAINER Alexander Todorov <atodorov@redhat.com>
-
-RUN dnf -y install wget diffutils beakerlib
-
-COPY schema.sql /
-COPY entrypoint-integration-test.sh /usr/local/bin/entrypoint-integration-test.sh
-ENTRYPOINT ["/usr/local/bin/entrypoint-integration-test.sh"]
diff --git a/Makefile b/Makefile
--- a/Makefile
+++ b/Makefile
@@ -4,50 +4,36 @@
 d = ${CURDIR}
 endif
 
-ORG_NAME=welder
 STORE ?= cs.repo
 MDDB ?= metadata.db
 
-weld-f25:
+weld-fedora:
 	git clone https://github.com/weldr/welder-deployment
-	$(MAKE) -C welder-deployment weld-f25
+	$(MAKE) -C welder-deployment weld-fedora
 	-rm -rf ./welder-deployment
 
-build: Dockerfile.build
-	if [ -n "$$TRAVIS" ]; then \
-	    sudo docker build -t $(ORG_NAME)/bdcs-build-img -f $< --cache-from $(ORG_NAME)/bdcs-build-img:latest .; \
-	else \
-	    sudo docker build -t $(ORG_NAME)/bdcs-build-img -f $< .; \
-	fi;
-	sudo docker create --name build-cont $(ORG_NAME)/bdcs-build-img /bin/bash
-	sudo docker cp build-cont:/usr/local/bin/bdcs ./bdcs
-	sudo docker cp build-cont:/usr/local/libexec/weldr/bdcs-import ./bdcs-import
-	sudo docker cp build-cont:/usr/local/libexec/weldr/bdcs-export ./bdcs-export
-	sudo docker rm build-cont
-
-importer: build
-	sudo docker build -t $(ORG_NAME)/bdcs-import-img .
+build-and-test: Dockerfile.build
+	sudo docker build -t welder/bdcs-build-img -f $< .
+	sudo docker run --rm --security-opt label=disable -v `pwd`:/bdcs/ welder/bdcs-build-img
 
-integration-test: build Dockerfile.integration-test
-	sudo docker build -t $(ORG_NAME)/bdcs-integration-test -f Dockerfile.integration-test .
-	sudo docker run --name tests $(ORG_NAME)/bdcs-integration-test
+importer: build-and-test
+	sudo docker build -t welder/bdcs-import-img .
 
 
 # NOTE: The mddb and content store under ./mddb/ will be removed
 #       Unless KEEP_STORE=1 and KEEP_MDDB=1 are set.
 mddb:
-	@if [ ! -e ${d}/mddb ]; then \
-	    mkdir ${d}/mddb; \
-	fi;
 	sudo docker rm -f mddb-container || true
-	sudo docker run -v ${d}/mddb/:/mddb/ -v ${d}/rpms:/rpms:ro --security-opt="label=disable" \
+	sudo docker volume rm bdcs-mddb-volume || true
+	sudo docker volume create -d local --name bdcs-mddb-volume
+	sudo docker run -v bdcs-mddb-volume:/mddb/ -v ${d}/rpms:/rpms:ro --security-opt="label=disable" \
 	    --name mddb-container         \
 	    -e "IMPORT_URL=$(IMPORT_URL)" \
 	    -e "KEEP_STORE=$(KEEP_STORE)"   \
 	    -e "STORE=$(STORE)"             \
 	    -e "KEEP_MDDB=$(KEEP_MDDB)"   \
 	    -e "MDDB=$(MDDB)"             \
-	    $(ORG_NAME)/bdcs-import-img
+	    welder/bdcs-import-img
 	sudo docker rm mddb-container
 
 api-mddb:
@@ -64,62 +50,28 @@
 	    http://mirror.centos.org/centos/7/os/x86_64/Packages/bash-4.2.46-28.el7.x86_64.rpm \
 	    http://mirror.centos.org/centos/7/updates/x86_64/Packages/bash-4.2.46-29.el7_4.x86_64.rpm
 	sudo docker volume create -d local --name api-test-mddb-volume
-	sudo docker run -v ${d}/api-mddb:/mddb:z -v ${d}/api-rpms:/rpms:z,ro --security-opt="label:disable" $(ORG_NAME)/bdcs-import-img
+	sudo docker run -v ${d}/api-mddb:/mddb:z -v ${d}/api-rpms:/rpms:z,ro --security-opt="label:disable" welder/bdcs-import-img
 
 
 .PHONY: importer mddb api-mddb ci
 
-import-centos7:
-	make weld-f25
-	make importer
-	mkdir rpms/
-
-	if [ ! -e ${d}/mddb ]; then \
-	    mkdir ${d}/mddb;        \
-	fi;                         \
-
-	if [ -n "$$EXISTING_MDDB" ]; then                          \
-	    wget --progress=dot:giga "$$EXISTING_MDDB";            \
-	    gunzip -q `basename "$$EXISTING_MDDB"`;                \
-	    UNZIPPED=`basename "$$EXISTING_MDDB" | sed 's/.gz//'`; \
-	    mv $$UNZIPPED ${d}/mddb/$(MDDB);                       \
-	fi
-
-	if [ -n "$$EXISTING_STORE" ]; then                                          \
-	    STORE=`basename "$$EXISTING_STORE"`;                                    \
-	    ostree --repo=${d}/mddb/$$STORE init --mode=archive;                    \
-	    ostree --repo=${d}/mddb/$$STORE remote add --no-gpg-verify existing "$$EXISTING_STORE"; \
-	    # note: pulls with --depth=0, only the last commit                      \
-	    ostree --repo=${d}/mddb/$$STORE pull --mirror existing;                 \
-	fi                                                                          \
-
-	set -e
-	for REPO in http://mirror.centos.org/centos/7/os/x86_64/ \
-	            http://mirror.centos.org/centos/7/extras/x86_64/; do \
-	    export IMPORT_URL="$$REPO"; \
-	    export KEEP_STORE=1; \
-	    export STORE="$$STORE"; \
-	    export KEEP_MDDB=1; \
-	    make mddb; \
-	done
-
-ci: integration-test
+ci: build-and-test
 
 ci_after_success:
-	# copy coverage data & compiled binaries out of the container
-	sudo docker cp tests:/bdcs/dist ./bdcs/dist
-	sudo docker rm tests
-
-	sudo chown travis:travis -R ./bdcs/dist
-	[ -x ~/.cabal/bin/hpc-coveralls ] || cabal update && cabal install hpc-coveralls
-	cd bdcs/ && ~/.cabal/bin/hpc-coveralls --display-report test-bdcs bdcs bdcs-import bdcs-inspect inspect-groups inspect-ls inspect-nevras bdcs-export bdcs-tmpfiles bdcs-depsolve && cd ..
+	sudo docker run --rm --security-opt label=disable -v `pwd`:/bdcs/ \
+	    --env "TRAVIS=$$TRAVIS" --env "TRAVIS_JOB_ID=$$TRAVIS_JOB_ID" --entrypoint /usr/bin/make welder/bdcs-build-img coveralls
 
 	# upload artifacts on which other test activities depend
 	s3cmd sync -v -P ./bdcs/dist/build/bdcs-import/bdcs-import s3://weldr/bdcs-import
 	s3cmd sync -v -P ./bdcs/dist/build/bdcs-export/bdcs-export s3://weldr/bdcs-export
 
+coveralls: sandbox
+	[ -x .cabal-sandbox/bin/hpc-coveralls ] || cabal install hpc-coveralls
+	.cabal-sandbox/bin/hpc-coveralls --display-report test-bdcs bdcs
+
 sandbox:
-	[ -d .cabal-sandbox ] || cabal sandbox init
+	cabal update
+	cabal sandbox init
 
 hlint: sandbox
 	[ -x .cabal-sandbox/bin/happy ] || cabal install happy
@@ -127,7 +79,10 @@
 	cabal exec hlint .
 
 tests: sandbox
-	cabal install --dependencies-only --enable-tests
-	cabal configure --enable-tests --enable-coverage
+	cabal install --dependencies-only --enable-tests --force-reinstall
+	cabal configure --enable-tests --enable-coverage --prefix=/usr/local
 	cabal build
-	cabal test
+	cabal test --show-details=always
+
+install:
+	cabal install --prefix=/usr/local
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -35,20 +35,18 @@
 build an mddb and produces an image with that program.  Dockerfile then runs
 that image and produces the mddb.
 
-The Dockerfile depends on a base image, named weld/fedora:25, which needs have
+The Dockerfile depends on a base image, named welder/fedora:latest, which needs have
 been previously built. If it is not available it can be built from the
-welder-deployment repository by running `make weld-f25`.
+welder-deployment repository by running `make weld-fedora`.
 
 The Makefile lays out the exact steps and can be used to simplify all this -
 just run `make importer mddb`.  If make is unavailable, just copy the steps
 out of there and run them manually.
 
-You will first need a volume to store the mddb in and a volume containing all
-the RPMs.  The Makefile expects that the mddb will be put into $PWD/mddb, and
-that the RPMs are in $PWD/rpms.
+The Makefile expects that the RPMs are in $PWD/rpms.
 
-After completion, the mddb will be in $PWD/mddb/metadata.db and the ostree
-based content store will be in $PWD/mddb/cs.repo/
+After completion, the mddb and content store will be in a bdcs-mddb-volume
+docker volume.
 
 Preparing local development environment for Haskell
 ===================================================
@@ -100,60 +98,3 @@
     $ cabal install --enable-tests --enable-coverage
     $ cabal test
     $ firefox ./dist/hpc/vanilla/tix/*/hpc_index.html
-
-OSTree cheat sheet
-==================
-
-After importing RPMs (via the `import` executable) the results are a
-`metadata.db` SQL database and a `cs.repo` directory containing an
-OSTree repository. Here are a few quick examples how to work with `ostree`:
-
-
-To see what references aka "branches" are in the repo:
-
-    ostree --repo=cs.repo/ refs
-    master
-
-
-To see the commit log (use `less` because ostree doesn't paginate like git):
-
-    ostree --repo=cs.repo/ log master
-    commit 816b63ab93a7a866d598c552f212c3a407648096521fde74cc9aa317730da8b1
-    Date:  2017-07-03 16:32:39 +0000
-    
-        Import of zsh-html into the repo
-    
-    commit f3d66bf3b40e269eac7ed62b6d6f7afdeb5059b17e1b8737aec8b52a03ea82c6
-    Date:  2017-07-03 16:32:38 +0000
-    
-        Import of zsh into the repo
-    
-    commit e370924c48e5b759c05d61b1c4960d96366a91e46eb7449a47c5064986029e50
-    Date:  2017-07-03 16:32:35 +0000
-    
-        Import of yum-rhn-plugin into the repo
-
-To find out the latest commit at `master`:
-
-    ostree --repo=cs.repo/ rev-parse master
-    816b63ab93a7a866d598c552f212c3a407648096521fde74cc9aa317730da8b1
-
-To see what files are inside a particular commit:
-
-    ostree --repo=cs.repo/ ls -RC 816b63ab93a7a866d598c552f212c3a407648096521fde74cc9aa317730da8b1
-    d00755 0 0      0 30bdab0c9a4156b26a923831f0e1c6ba6141c0a8e35c61f30e8febffe7f78de0 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /
-    d00755 0 0      0 eeae4a3c7450b786b3d9a6958ef2195c99c1867c2040d9153395e13f38b1ca7b 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /usr
-    d00755 0 0      0 0e1e668a21df0ef296e0a7287509b9bac8ae2a03bf6849954b3d0ef905b0cd9a 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /usr/share
-    d00755 0 0      0 d5c72afb0dc8197bba6249a8cdfcf155eed0e1d8bf3d3bd02a4e53f3d8c42b37 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /usr/share/doc
-    d00755 0 0      0 58efea079328274a2845195529729b190b31b06cc16b5f31c2dc1e2f88825563 446a0ef11b7cc167f3b603e585c7eeeeb675faa412d5ec73f62988eb0b6c5488 /usr/share/doc/zsh-html-5.0.2
-    -00644 0 0   1724 6c691ad9ce0f053823e3fe34795d911170bac0f78f9231389c2e9e2e1271f73a /usr/share/doc/zsh-html-5.0.2/Aliasing.html
-    -00644 0 0   1892 835ffd08dba662f47c7eb3164ae76aa5903363c63d3d606268c0ba928b725e6e /usr/share/doc/zsh-html-5.0.2/Alternate-Forms-For-Complex-Commands.html
-    -00644 0 0   1830 59184f18d807a6b9fc963b709ef82dba4d00f536388935aa79b74160fe90cbfe /usr/share/doc/zsh-html-5.0.2/Alternative-Completion.html
-    -00644 0 0   1734 b1bd5813c780a0862843fd3f468021c9358f5852c8a2029cb6857fb64dd2aed1 /usr/share/doc/zsh-html-5.0.2/Arguments.html
-    -00644 0 0  17635 89309b924ef3874172c73bab3c45eab56da0b847d6328dc387e0e1c5b3dfa633 /usr/share/doc/zsh-html-5.0.2/Arithmetic-Evaluation.html
-
-**NOTE:** `-R` means recursive, `-C` displays file checksums
-
-To check out aka export a commit into a filesystem tree:
-
-    sudo ostree --repo=cs.repo/ checkout 816b63ab93a7a866d598c552f212c3a407648096521fde74cc9aa317730da8b1 some.dir/
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -13,37 +13,64 @@
 -- You should have received a copy of the GNU Lesser General Public
 -- License along with this library; if not, see <http://www.gnu.org/licenses/>.
 
+{-# LANGUAGE CPP #-}
+
 module Main(main)
  where
 
 import Data.List(isPrefixOf)
-import Distribution.PackageDescription(Executable(..), GenericPackageDescription, HookedBuildInfo, PackageDescription(..))
+import Distribution.PackageDescription(Executable(..), GenericPackageDescription(..), HookedBuildInfo, PackageDescription(..))
 import Distribution.Simple(defaultMainWithHooks, simpleUserHooks)
-import Distribution.Simple.Install(install)
 import Distribution.Simple.InstallDirs(InstallDirs(..), fromPathTemplate, toPathTemplate)
 import Distribution.Simple.LocalBuildInfo(LocalBuildInfo(..))
 import Distribution.Simple.UserHooks(UserHooks(..))
-import Distribution.Simple.Setup(ConfigFlags, CopyFlags)
 import System.FilePath((</>))
 
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2, 0, 0)
+import Distribution.Types.UnqualComponentName(unUnqualComponentName)
+import Distribution.Types.ExecutableScope(ExecutableScope(..))
+import Distribution.Simple.Setup(ConfigFlags)
+#else
+import Distribution.Simple.Install(install)
+import Distribution.Simple.Setup(ConfigFlags, CopyFlags)
+#endif
+
 main :: IO ()
-main = defaultMainWithHooks $ simpleUserHooks { confHook = bdcsConf,
-                                                copyHook = bdcsCopy }
+main = defaultMainWithHooks bdcsHooks
 
--- Make sure $libexecdir gets "weldr/" appended to it.  This will affect both the installation location
--- for anything that should go into $libexecdir (like our subcommand programs) as well as the auto
--- generated Paths_bdcs.hs file.
+-- Handle the libexec paths, and differences between Cabal-1.x and Cabal-2.x.
 --
--- This also means if you pass --libexecdir= to "cabal configure" or any other program, you should not
--- add "weldr/" to it.  Otherwise you'll get it in there twice.
+-- On Cabal-2.x, we can specify a scope of "private" on libexec executables.
+-- This can be done directly in the .cabal file when we remove support for Cabal < 2.0.
+#if defined(MIN_VERSION_Cabal) && MIN_VERSION_Cabal(2, 0, 0)
+bdcsHooks :: UserHooks
+bdcsHooks = simpleUserHooks { confHook = bdcsConf }
+
 bdcsConf :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo
 bdcsConf (descr, hbi) flags = do
     lbi <- confHook simpleUserHooks (descr, hbi) flags
-    let dest = mangle $ libexecdir $ installDirTemplates lbi
-    return $ lbi { installDirTemplates = (installDirTemplates lbi) { libexecdir = dest } }
+
+    -- Modify the executable list to change the scope of the libexec executables
+    let localDesc = localPkgDescr lbi
+        scopedLbi = lbi { localPkgDescr = localDesc { executables = map mangleExec (executables localDesc) } }
+
+    -- Add weldr/ to the libexecdir
+    return $ addLibexecWeldr scopedLbi
  where
-    mangle = toPathTemplate . (</> "weldr") . fromPathTemplate
+    mangleExec :: Executable -> Executable
+    mangleExec exe =
+        if isSubcommand (unUnqualComponentName $ exeName exe) then exe{exeScope = ExecutablePrivate}
+        else exe
 
+#else
+-- On Cabal-1.x, change the destination directory of subcomponents during the copy step
+bdcsHooks :: UserHooks
+bdcsHooks = simpleUserHooks { confHook = bdcsConf,
+                              copyHook = bdcsCopy }
+
+bdcsConf :: (GenericPackageDescription, HookedBuildInfo) -> ConfigFlags -> IO LocalBuildInfo
+bdcsConf (descr, hbi) flags = addLibexecWeldr <$> confHook simpleUserHooks (descr, hbi) flags
+
 bdcsCopy :: PackageDescription -> LocalBuildInfo -> UserHooks -> CopyFlags -> IO ()
 bdcsCopy pkg lbi _ flags = do
     -- First, install everything that's not a subcommand.  That is almost everything
@@ -55,9 +82,6 @@
     let (subPkg, subLbi) = extractSubComponents pkg lbi
     install subPkg subLbi flags
 
-isSubcommand :: String -> Bool
-isSubcommand s = "inspect-" `isPrefixOf` s || "bdcs-" `isPrefixOf` s
-
 extractMainComponents :: PackageDescription -> LocalBuildInfo -> (PackageDescription, LocalBuildInfo)
 extractMainComponents pkg lbi = let
     pkg' = pkg { executables = filter (not . isSubcommand . exeName)
@@ -74,3 +98,21 @@
     lbi' = lbi { installDirTemplates = (installDirTemplates lbi) { bindir = dest } }
  in
     (pkg', lbi')
+
+#endif
+
+isSubcommand :: String -> Bool
+isSubcommand s = "inspect-" `isPrefixOf` s || "bdcs-" `isPrefixOf` s
+
+-- Make sure $libexecdir gets "weldr/" appended to it.  This will affect both the installation location
+-- for anything that should go into $libexecdir (like our subcommand programs) as well as the auto
+-- generated Paths_bdcs.hs file.
+--
+-- This also means if you pass --libexecdir= to "cabal configure" or any other program, you should not
+-- add "weldr/" to it.  Otherwise you'll get it in there twice.
+addLibexecWeldr :: LocalBuildInfo -> LocalBuildInfo
+addLibexecWeldr lbi =
+    let dest = mangle $ libexecdir $ installDirTemplates lbi
+    in lbi { installDirTemplates = (installDirTemplates lbi) { libexecdir = dest } }
+ where
+    mangle = toPathTemplate . (</> "weldr") . fromPathTemplate
diff --git a/bdcs.cabal b/bdcs.cabal
--- a/bdcs.cabal
+++ b/bdcs.cabal
@@ -1,5 +1,5 @@
 name:                   bdcs
-version:                0.2.0
+version:                0.2.1
 synopsis:               Tools for managing a content store of software packages
 description:            This module provides a library and various tools for managing a content store and
                         metadata database.  These store the contents of software packages that make up a
@@ -24,7 +24,6 @@
 extra-source-files:     ChangeLog.md,
                         Dockerfile,
                         Dockerfile.build,
-                        Dockerfile.integration-test,
                         entrypoint-integration-test.sh,
                         entrypoint.sh,
                         cabal.config,
@@ -40,7 +39,7 @@
 
 custom-setup
     setup-depends:      base,
-                        Cabal,
+                        Cabal >= 1.10 && < 2.1,
                         filepath
 
 source-repository       head
@@ -61,6 +60,7 @@
                         BDCS.Depclose,
                         BDCS.Depsolve,
                         BDCS.Exceptions,
+                        BDCS.Export,
                         BDCS.Export.Directory,
                         BDCS.Export.FSTree,
                         BDCS.Export.Qcow2,
@@ -123,7 +123,7 @@
                         cond >= 0.4.1.1 && < 0.5.0.0,
                         conduit >= 1.2.8 && < 1.3,
                         conduit-combinators >= 1.1.0 && < 1.2,
-                        conduit-extra >= 1.1.0 && < 1.2,
+                        conduit-extra >= 1.1.0 && < 1.3,
                         containers >= 0.5.7.1 && < 0.6,
                         content-store >= 0.2.0 && < 0.3.0,
                         cpio-conduit >= 0.7.0 && < 0.8.0,
@@ -178,7 +178,8 @@
     hs-source-dirs:     src/tools
 
     other-modules:      Utils.GetOpt,
-                        Utils.Subcommands
+                        Utils.Subcommands,
+                        Paths_bdcs
 
     build-depends:      bdcs,
                         base >= 4.7 && < 5.0,
@@ -219,7 +220,8 @@
 
     other-modules:      Utils.GetOpt,
                         Utils.IO,
-                        Utils.Subcommands
+                        Utils.Subcommands,
+                        Paths_bdcs
 
     build-depends:      bdcs,
                         base >= 4.7 && < 5.0,
@@ -240,7 +242,8 @@
                         src/tools/inspect,
                         src/tools
 
-    other-modules:      Utils.GetOpt,
+    other-modules:      Utils.Exceptions,
+                        Utils.GetOpt,
                         Utils.IO,
                         Utils.KeyVal
 
@@ -293,7 +296,8 @@
                         src/tools/inspect,
                         src/tools
 
-    other-modules:      Utils.GetOpt,
+    other-modules:      Utils.Exceptions,
+                        Utils.GetOpt,
                         Utils.IO
 
     build-depends:      bdcs,
@@ -388,7 +392,10 @@
                         time >= 1.6.0.1 && < 2.0,
                         unix >= 2.7.2.1 && < 2.8.0.0
 
-    ghc-options:        -Wall
+    -- the modules compiled with -DTEST are automatically pulled in from src/
+    -- based on what the tests import, and that's how we want it. Don't warn
+    -- about unlisted modules.
+    ghc-options:        -Wall -Wno-unrecognised-warning-flags -Wno-missing-home-modules
     cpp-options:        -DTEST
 
     default-language:   Haskell2010
diff --git a/entrypoint-integration-test.sh b/entrypoint-integration-test.sh
--- a/entrypoint-integration-test.sh
+++ b/entrypoint-integration-test.sh
@@ -2,26 +2,21 @@
 
 set -ex
 
-cd /bdcs/
+# first build the application
+make hlint tests install
 
 ./tests/test_tmpfiles.sh
-grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1
+grep RESULT_STRING /var/tmp/beakerlib-*/TestResults | grep -v PASS && exit 1
 
 ./tests/test_import.sh
-grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1
+grep RESULT_STRING /var/tmp/beakerlib-*/TestResults | grep -v PASS && exit 1
 
 ./tests/test_export.sh
-grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1
+grep RESULT_STRING /var/tmp/beakerlib-*/TestResults | grep -v PASS && exit 1
 
 ./tests/test_depsolve.sh
-grep RESULT_STRING=PASS /var/tmp/beakerlib-*/TestResults || exit 1
+grep RESULT_STRING /var/tmp/beakerlib-*/TestResults | grep -v PASS && exit 1
 
 # collect coverage data from unit tests and binaries
-mkdir ./dist/hpc/vanilla/tix/bdcs-tmpfiles/
-mkdir ./dist/hpc/vanilla/tix/bdcs-import/
-mkdir ./dist/hpc/vanilla/tix/bdcs-export/
-mkdir ./dist/hpc/vanilla/tix/bdcs-depsolve/
-mv bdcs-tmpfiles.tix ./dist/hpc/vanilla/tix/bdcs-tmpfiles/
-mv bdcs-import.tix ./dist/hpc/vanilla/tix/bdcs-import/
-mv bdcs-export.tix ./dist/hpc/vanilla/tix/bdcs-export/
-mv bdcs-depsolve.tix ./dist/hpc/vanilla/tix/bdcs-depsolve/
+mkdir ./dist/hpc/vanilla/tix/bdcs/
+mv bdcs.tix ./dist/hpc/vanilla/tix/bdcs/
diff --git a/src/BDCS/Build/NPM.hs b/src/BDCS/Build/NPM.hs
--- a/src/BDCS/Build/NPM.hs
+++ b/src/BDCS/Build/NPM.hs
@@ -43,6 +43,8 @@
 import BDCS.Label.FileLabels(apply)
 import BDCS.NPM.SemVer(SemVer, SemVerRangeSet, parseSemVer, parseSemVerRangeSet, satisfies, toText)
 
+{-# ANN rebuildNPM ("HLint: ignore Use ." :: String) #-}
+
 rebuildNPM :: (MonadBaseControl IO m, MonadIO m, MonadError String m, MonadResource m) => Key Sources -> SqlPersistT m [Key Builds]
 rebuildNPM sourceId = do
     -- get the name and version for this source
diff --git a/src/BDCS/Builds.hs b/src/BDCS/Builds.hs
--- a/src/BDCS/Builds.hs
+++ b/src/BDCS/Builds.hs
@@ -28,6 +28,8 @@
 import BDCS.KeyType
 import BDCS.KeyValue(findKeyValue, insertKeyValue)
 
+{-# ANN findBuild ("HLint: ignore Use ." :: String) #-}
+
 -- | Find a single build of a software package in the database, returning the database key
 -- for that build if it exists.  All arguments are required and must be matched for this
 -- function to return anything.  Note that conceptually, a build is of some software source
diff --git a/src/BDCS/Depclose.hs b/src/BDCS/Depclose.hs
--- a/src/BDCS/Depclose.hs
+++ b/src/BDCS/Depclose.hs
@@ -137,7 +137,7 @@
         -- Now the recursive part. First, grab everything from the requirements table for this group:
         -- TODO maybe do something with strength, context, etc.
 
-        requirements <- getRequirementsForGroup groupId RT.Runtime >>= mapM reqToDep
+        requirements <- getRequirementsForGroup groupId RT.Runtime RT.Must >>= mapM reqToDep
 
         -- Resolve each requirement to a list of group ids. Each group id is a possibility for satisfying
         -- the requirement. An empty list means the requirement cannot be satisfied.
diff --git a/src/BDCS/Export.hs b/src/BDCS/Export.hs
new file mode 100644
--- /dev/null
+++ b/src/BDCS/Export.hs
@@ -0,0 +1,68 @@
+{-# LANGUAGE FlexibleContexts #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RankNTypes #-}
+
+-- |
+-- Module: BDCS.Export
+-- Copyright: (c) 2017-2018 Red Hat, Inc.
+-- License: LGPL
+--
+-- Maintainer: https://github.com/weldr
+-- Stability: alpha
+-- Portability: portable
+--
+-- Top-level function for exporting objects from the BDCS.
+
+module BDCS.Export(export)
+ where
+
+import           Control.Conditional(cond)
+import           Control.Monad.Except(MonadError, runExceptT, throwError)
+import           Control.Monad.IO.Class(MonadIO, liftIO)
+import           Control.Monad.Trans.Resource(MonadBaseControl, MonadResource)
+import           Data.Conduit(Consumer, (.|), runConduit, runConduitRes)
+import           Data.Conduit.List as CL
+import           Data.ContentStore(openContentStore)
+import           Data.List(isSuffixOf)
+import qualified Data.Text as T
+import           Database.Esqueleto(SqlPersistT)
+
+import qualified BDCS.CS as CS
+import           BDCS.DB(Files)
+import qualified BDCS.Export.Directory as Directory
+import           BDCS.Export.FSTree(filesToTree, fstreeSource)
+import qualified BDCS.Export.Ostree as Ostree
+import qualified BDCS.Export.Qcow2 as Qcow2
+import qualified BDCS.Export.Tar as Tar
+import           BDCS.Export.Utils(runHacks, runTmpfiles)
+import           BDCS.Files(groupIdToFilesC)
+import           BDCS.Groups(getGroupIdC)
+
+export :: (MonadBaseControl IO m, MonadError String m, MonadIO m, MonadResource m) => FilePath -> FilePath -> [T.Text] -> SqlPersistT m ()
+export repo out_path things | kernelMissing out_path things = throwError "ERROR: ostree exports need a kernel package included"
+                            | otherwise                     = do
+    let objectSink = cond [(".tar" `isSuffixOf` out_path,   CS.objectToTarEntry .| Tar.tarSink out_path),
+                           (".qcow2" `isSuffixOf` out_path, Qcow2.qcow2Sink out_path),
+                           (".repo" `isSuffixOf` out_path,  Ostree.ostreeSink out_path),
+                           (otherwise,                      directoryOutput out_path)]
+
+    runExceptT (openContentStore repo) >>= \case
+        Left e   -> throwError $ show e
+        Right cs -> do
+            fstree <- runConduit $ CL.sourceList things
+                          .| getGroupIdC
+                          .| groupIdToFilesC
+                          .| filesToTree
+            runConduitRes $ fstreeSource fstree .| CS.filesToObjectsC cs .| objectSink
+ where
+    directoryOutput :: (MonadError String m, MonadIO m) => FilePath -> Consumer (Files, CS.Object) m ()
+    directoryOutput path = do
+        -- Apply tmpfiles.d to the directory first
+        liftIO $ runTmpfiles path
+
+        Directory.directorySink path
+        liftIO $ runHacks path
+
+    kernelMissing :: FilePath -> [T.Text] -> Bool
+    kernelMissing out lst = ".repo" `isSuffixOf` out && not (any ("kernel-" `T.isPrefixOf`) lst)
diff --git a/src/BDCS/Export/Utils.hs b/src/BDCS/Export/Utils.hs
--- a/src/BDCS/Export/Utils.hs
+++ b/src/BDCS/Export/Utils.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE OverloadedStrings #-}
+
 -- |
 -- Module: BDCS.Export.Utils
 -- Copyright: (c) 2017 Red Hat, Inc.
@@ -10,18 +12,20 @@
 -- Miscellaneous utilities useful in exporting objects.
 
 module BDCS.Export.Utils(runHacks,
-                         runTmpfiles)
+                         runTmpfiles,
+                         supportedOutputs)
  where
 
-import Control.Conditional(whenM)
-import Control.Exception(tryJust)
-import Control.Monad(guard)
-import Data.List(intercalate)
-import Data.List.Split(splitOn)
-import System.Directory(createDirectoryIfMissing, doesFileExist, listDirectory, removePathForcibly, renameFile)
-import System.FilePath((</>))
-import System.IO.Error(isDoesNotExistError)
-import System.Process(callProcess)
+import           Control.Conditional(whenM)
+import           Control.Exception(tryJust)
+import           Control.Monad(guard)
+import           Data.List(intercalate)
+import           Data.List.Split(splitOn)
+import qualified Data.Text as T
+import           System.Directory(createDirectoryIfMissing, doesFileExist, listDirectory, removePathForcibly, renameFile)
+import           System.FilePath((</>))
+import           System.IO.Error(isDoesNotExistError)
+import           System.Process(callProcess)
 
 import BDCS.Export.TmpFiles(setupFilesystem)
 
@@ -74,3 +78,10 @@
 runTmpfiles exportPath = do
     configPath <- getDataFileName "tmpfiles-default.conf"
     setupFilesystem exportPath configPath
+
+-- | List the supported output formats.
+-- Note that any time a new output format file is added in BDCS/Export (and thus to
+-- the runCommand block in tools/export.hs), it should also be added here.  There's
+-- not really any better way to accomplish this.
+supportedOutputs :: [T.Text]
+supportedOutputs = ["directory", "ostree", "qcow2", "tar"]
diff --git a/src/BDCS/Files.hs b/src/BDCS/Files.hs
--- a/src/BDCS/Files.hs
+++ b/src/BDCS/Files.hs
@@ -38,6 +38,11 @@
 import BDCS.DB
 import BDCS.Utils.Conduit(awaitWith)
 
+{-# ANN getKeyValuesForFile ("HLint: ignore Use ." :: String) #-}
+{-# ANN groupIdToFiles ("HLint: ignore Use ." :: String) #-}
+{-# ANN sourceIdToFiles ("HLint: ignore Use ." :: String) #-}
+{-# ANN pathToGroupId ("HLint: ignore Use ." :: String) #-}
+
 insertFiles :: MonadIO m => [Files] -> SqlPersistT m [Key Files]
 insertFiles = mapM insert
 
diff --git a/src/BDCS/GroupKeyValue.hs b/src/BDCS/GroupKeyValue.hs
--- a/src/BDCS/GroupKeyValue.hs
+++ b/src/BDCS/GroupKeyValue.hs
@@ -29,6 +29,9 @@
 import BDCS.KeyType
 import BDCS.KeyValue(findKeyValue, insertKeyValue)
 
+{-# ANN getKeyValuesForGroup ("HLint: ignore Use ." :: String) #-}
+{-# ANN getGroupsByKeyVal ("HLint: ignore Use ." :: String) #-}
+
 insertGroupKeyValue :: MonadIO m => KeyType -> T.Text -> Maybe T.Text -> Key Groups -> SqlPersistT m (Key GroupKeyValues)
 insertGroupKeyValue k v e groupId =
     maybeKey (insertKeyValue k (Just v) e >>= \kvId -> insert $ GroupKeyValues groupId kvId)
diff --git a/src/BDCS/Groups.hs b/src/BDCS/Groups.hs
--- a/src/BDCS/Groups.hs
+++ b/src/BDCS/Groups.hs
@@ -47,6 +47,12 @@
 import qualified BDCS.ReqType as RT
 import           BDCS.RPM.Utils(splitFilename)
 
+{-# ANN findGroupRequirements ("HLint: ignore Use ." :: String) #-}
+{-# ANN findRequires ("HLint: ignore Use ." :: String) #-}
+{-# ANN getRequirementsForGroup ("HLint: ignore Use ." :: String) #-}
+{-# ANN nameToGroupIds ("HLint: ignore Use ." :: String) #-}
+{-# ANN nevraToGroupId ("HLint: ignore Use ." :: String) #-}
+
 findGroupRequirements :: MonadIO m => Key Groups -> Key Requirements -> SqlPersistT m (Maybe (Key GroupRequirements))
 findGroupRequirements groupId reqId = firstKeyResult $
     select $ from $ \r -> do
@@ -125,12 +131,13 @@
     epoch (Just e) = e `T.append` ":"
     epoch Nothing  = ""
 
-getRequirementsForGroup :: MonadIO m => Key Groups -> RT.ReqContext -> SqlPersistT m [Requirements]
-getRequirementsForGroup groupId context = do
+getRequirementsForGroup :: MonadIO m => Key Groups -> RT.ReqContext -> RT.ReqStrength -> SqlPersistT m [Requirements]
+getRequirementsForGroup groupId context strength = do
     vals <- select $ from $ \(reqs `InnerJoin` groupreqs) -> do
             on     $ reqs ^. RequirementsId ==. groupreqs ^. GroupRequirementsReq_id
             where_ $ groupreqs ^. GroupRequirementsGroup_id ==. val groupId &&.
-                     reqs ^. RequirementsReq_context ==. val context
+                     reqs ^. RequirementsReq_context ==. val context &&.
+                     reqs ^. RequirementsReq_strength ==. val strength
             return   reqs
     return $ map entityVal vals
 
diff --git a/src/BDCS/Import/RPM.hs b/src/BDCS/Import/RPM.hs
--- a/src/BDCS/Import/RPM.hs
+++ b/src/BDCS/Import/RPM.hs
@@ -72,6 +72,8 @@
 import BDCS.Scripts(insertScript)
 #endif
 
+{-# ANN buildImported ("HLint: ignore Use ." :: String) #-}
+
 buildImported :: MonadResource m => [Tag] ->  SqlPersistT m Bool
 buildImported sigs =
     case findStringTag "SHA1Header" sigs of
diff --git a/src/BDCS/KeyValue.hs b/src/BDCS/KeyValue.hs
--- a/src/BDCS/KeyValue.hs
+++ b/src/BDCS/KeyValue.hs
@@ -34,6 +34,8 @@
 import BDCS.DB
 import BDCS.KeyType
 
+{-# ANN findKeyValue ("HLint: ignore Use ." :: String) #-}
+
 findKeyValue :: MonadIO m => KeyType -> Maybe T.Text -> Maybe T.Text -> SqlPersistT m (Maybe (Key KeyVal))
 findKeyValue k v e = firstKeyResult $
     select $ from $ \kv -> do
diff --git a/src/BDCS/Packages.hs b/src/BDCS/Packages.hs
--- a/src/BDCS/Packages.hs
+++ b/src/BDCS/Packages.hs
@@ -28,6 +28,9 @@
 import BDCS.KeyValue(insertKeyValue)
 import BDCS.KeyType
 
+{-# ANN filesInPackage ("HLint: ignore Use ." :: String) #-}
+{-# ANN findPackage ("HLint: ignore Use ." :: String) #-}
+
 filesInPackage :: MonadIO m => T.Text -> SqlPersistT m [T.Text]
 filesInPackage name = do
     results <- select $ from $ \(files `InnerJoin` key_val `InnerJoin` file_key_values) -> do
diff --git a/src/BDCS/Scripts.hs b/src/BDCS/Scripts.hs
--- a/src/BDCS/Scripts.hs
+++ b/src/BDCS/Scripts.hs
@@ -26,6 +26,8 @@
 
 import BDCS.DB
 
+{-# ANN findScript ("HLint: ignore Use ." :: String) #-}
+
 -- | Find a single script in the database, returning the key for that script if it
 -- exists.  It is possible for multiple very similar scripts to exist in the same
 -- database (or even, scripts with identical bodies but that differ in other ways)
diff --git a/src/BDCS/Sources.hs b/src/BDCS/Sources.hs
--- a/src/BDCS/Sources.hs
+++ b/src/BDCS/Sources.hs
@@ -27,6 +27,8 @@
 import BDCS.KeyType
 import BDCS.KeyValue(findKeyValue)
 
+{-# ANN findSource ("HLint: ignore Use ." :: String) #-}
+
 -- | Given a version number and a key to a 'Projects' record, find a matching software
 -- source in the database.  If it exists, the database key is returned.
 findSource :: MonadIO m => T.Text -> Key Projects -> SqlPersistT m (Maybe (Key Sources))
diff --git a/src/tools/export.hs b/src/tools/export.hs
--- a/src/tools/export.hs
+++ b/src/tools/export.hs
@@ -13,37 +13,19 @@
 -- You should have received a copy of the GNU Lesser General Public
 -- License along with this library; if not, see <http://www.gnu.org/licenses/>.
 
-{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE LambdaCase #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE RankNTypes #-}
 
-import           Control.Conditional(cond, ifM)
-import           Control.Monad(unless, when)
-import           Control.Monad.Except(MonadError, runExceptT)
-import           Control.Monad.IO.Class(MonadIO, liftIO)
-import           Data.Conduit(Consumer, (.|), runConduit, runConduitRes)
-import qualified Data.Conduit.List as CL
-import           Data.ContentStore(openContentStore, runCsMonad)
-import           Data.List(isSuffixOf)
+import           Control.Conditional(ifM)
+import           Control.Monad.Except(runExceptT)
 import qualified Data.Text as T
 import           System.Directory(doesFileExist, removePathForcibly)
 import           System.Environment(getArgs)
-import           System.Exit(exitFailure)
+import           System.Exit(exitFailure, exitSuccess)
 
-import qualified BDCS.CS as CS
-import           BDCS.DB(Files, checkAndRunSqlite)
-import qualified BDCS.Export.Directory as Directory
-import           BDCS.Export.FSTree(filesToTree, fstreeSource)
-import qualified BDCS.Export.Qcow2 as Qcow2
-import qualified BDCS.Export.Ostree as Ostree
-import qualified BDCS.Export.Tar as Tar
-import           BDCS.Export.Utils(runHacks, runTmpfiles)
-import           BDCS.Files(groupIdToFilesC)
-import           BDCS.Groups(getGroupIdC)
-import           BDCS.Utils.Either(whenLeft)
-import           BDCS.Utils.Monad(concatMapM)
-import           BDCS.Version
+import BDCS.DB(checkAndRunSqlite)
+import BDCS.Export(export)
+import BDCS.Utils.Monad(concatMapM)
+import BDCS.Version
 
 import Utils.GetOpt(commandLineArgs)
 
@@ -72,52 +54,11 @@
     -- TODO group id?
     exitFailure
 
-needKernel :: IO ()
-needKernel = do
-    printVersion "export"
-    putStrLn "ERROR: ostree exports need a kernel package included"
-    exitFailure
-
-runCommand :: FilePath -> FilePath -> FilePath -> [String] -> IO ()
-runCommand db repo out_path fileThings = do
-    things <- map T.pack <$> expandFileThings fileThings
-
-    cs <- runCsMonad (openContentStore repo) >>= \case
-        Left e  -> print e >> exitFailure
-        Right r -> return r
-
-    when (".repo" `isSuffixOf` out_path) $
-        unless (any ("kernel-" `T.isPrefixOf`) things) needKernel
-
-    let (handler, objectSink) = cond [(".tar" `isSuffixOf` out_path,   (cleanupHandler out_path, CS.objectToTarEntry .| Tar.tarSink out_path)),
-                                      (".qcow2" `isSuffixOf` out_path, (cleanupHandler out_path, Qcow2.qcow2Sink out_path)),
-                                      (".repo" `isSuffixOf` out_path,  (cleanupHandler out_path, Ostree.ostreeSink out_path)),
-                                      (otherwise,                      (print, directoryOutput out_path))]
-
-    result <- runExceptT $ do
-        -- Build the filesystem tree to export
-        fstree <- checkAndRunSqlite (T.pack db) $ runConduit $ CL.sourceList things
-                    .| getGroupIdC
-                    .| groupIdToFilesC
-                    .| filesToTree
-
-        -- Traverse the tree and export the file contents
-        runConduitRes $ fstreeSource fstree .| CS.filesToObjectsC cs .| objectSink
-
-    whenLeft result (\e -> handler e >> exitFailure)
- where
-    directoryOutput :: (MonadError String m, MonadIO m) => FilePath -> Consumer (Files, CS.Object) m ()
-    directoryOutput path = do
-        -- Apply tmpfiles.d to the directory first
-        liftIO $ runTmpfiles path
-
-        Directory.directorySink path
-        liftIO $ runHacks path
-
-    cleanupHandler :: Show a => FilePath -> a -> IO ()
-    cleanupHandler path e = print e >> removePathForcibly path
-
 main :: IO ()
 main = commandLineArgs <$> getArgs >>= \case
-    Just (db, repo, out_path:things) -> runCommand db repo out_path things
+    Just (db, repo, out_path:things) -> do things' <- map T.pack <$> expandFileThings things
+                                           result  <- runExceptT $ checkAndRunSqlite (T.pack db) $ export repo out_path things'
+                                           case result of
+                                               Left err -> removePathForcibly out_path >> print err >> exitFailure
+                                               Right _  -> exitSuccess
     _                                -> usage
diff --git a/tests/test_depsolve.sh b/tests/test_depsolve.sh
--- a/tests/test_depsolve.sh
+++ b/tests/test_depsolve.sh
@@ -7,9 +7,12 @@
 METADATA_DB="metadata.db"
 CS_REPO="/tmp/depsolve.repo"
 
+export PATH="./dist/build/bdcs-import:./dist/build/bdcs-depsolve:$PATH"
+
+
 rlJournalStart
     rlPhaseStartSetup
-        rlRun "sqlite3 $METADATA_DB < ../schema.sql"
+        rlRun "sqlite3 $METADATA_DB < ./schema.sql"
         DNF_ROOT=`mktemp -d /tmp/dnf.root.XXXXXX`
         DNF_DOWNLOAD=`mktemp -d /tmp/dnf.download.XXXXXX`
     rlPhaseEnd
diff --git a/tests/test_export.sh b/tests/test_export.sh
--- a/tests/test_export.sh
+++ b/tests/test_export.sh
@@ -8,6 +8,9 @@
 METADATA_DB="./export_metadata.db"
 EXPORT_DIR="./exported-content.d/"
 
+export PATH="./dist/build/bdcs-import:./dist/build/bdcs-export:$PATH"
+
+
 function compare_with_rpm() {
     # Verify that contents of an exported directory have the same files as if
     # RPMs were installed via rpm.
@@ -74,7 +77,7 @@
 
 rlJournalStart
     rlPhaseStartSetup
-        rlRun "sqlite3 $METADATA_DB < ../schema.sql"
+        rlRun "sqlite3 $METADATA_DB < ./schema.sql"
         # filesystem package is required by the exporter
         rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/filesystem-3.2-21.el7.x86_64.rpm"
         rlRun "$BDCS import $METADATA_DB $CS_REPO file://`pwd`/filesystem-3.2-21.el7.x86_64.rpm"
@@ -100,7 +103,7 @@
     rlPhaseEnd
 
     rlPhaseStartTest "When exporting a non-existing package returns an error"
-        OUTPUT=`sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 NON-EXISTING`
+        OUTPUT=`$BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 NON-EXISTING`
         rlAssertNotEquals "On error exit code should not be zero" $? 0
         rlAssertEquals "On error output is as expected" "$OUTPUT" '"No such group NON-EXISTING"'
 
@@ -109,40 +112,34 @@
 
 
     rlPhaseStartTest "When exporting existing package exported contents match what's inside the RPM"
-        rlRun "sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch"
+        rlRun "$BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch"
         compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm yum-rhn-plugin-2.0.1-9.el7.noarch.rpm
         sudo rm -rf $EXPORT_DIR
     rlPhaseEnd
 
     rlPhaseStartTest "When exporting existing package into .tar image untarred contents match the contents of RPM"
-        rlRun "sudo $BDCS export $METADATA_DB $CS_REPO exported.tar filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch"
+        rlRun "$BDCS export $METADATA_DB $CS_REPO exported.tar filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch yum-rhn-plugin-2.0.1-9.el7.noarch"
 
-        mkdir tar_contents && pushd tar_contents/ && tar xvf ../exported.tar && popd
+        mkdir tar_contents && pushd tar_contents/ && tar xf ../exported.tar && popd
         compare_with_rpm tar_contents/ filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm yum-rhn-plugin-2.0.1-9.el7.noarch.rpm
         sudo rm -rf tar_contents/ exported.tar
     rlPhaseEnd
 
 
-    rlPhaseStartTest "When exporting two conflicting packages on a symlink the first symlink to be exported wins"
+    rlPhaseStartTest "When exporting two conflicting packages bdcs reports error"
         # in libcmpiCppImpl0:
         # libcmpiCppImpl.so and libcmpiCppImpl.so.0 are symlinks to libcmpiCppImpl.so.0.0.0
 
         # in tog-pegasus-libs:
         # libcmpiCppImpl.so is a symlink to libcmpiCppImpl.so.1
+        OUTPUT=`$BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch libcmpiCppImpl0-2.0.3-5.el7.x86_64 tog-pegasus-libs-2:2.14.1-5.el7.x86_64`
+        rlAssertNotEquals "On error exit code should not be zero" $? 0
+        rlAssertEquals "On error output is as expected" "$OUTPUT" '"Unable to resolve path /usr/lib64/libcmpiCppImpl.so, non-directory object exists at /usr/lib64/libcmpiCppImpl.so.0.0.0"'
 
-        # first libcmpiCppImpl0, second tog-pegasus-libs
-        rlRun "$BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch libcmpiCppImpl0-2.0.3-5.el7.x86_64 tog-pegasus-libs-2:2.14.1-5.el7.x86_64 2>&1"
-        # conflict is in tog-pegasus-libs which is the second package in the list
-        # make sure libcmpiCppImpl0 wins
-        compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm libcmpiCppImpl0-2.0.3-5.el7.x86_64.rpm
         sudo rm -rf $EXPORT_DIR
-
-        # first tog-pegasus-libs, second libcmpiCppImpl0
-        rlRun "sudo $BDCS export $METADATA_DB $CS_REPO $EXPORT_DIR filesystem-3.2-21.el7.x86_64 setup-2.8.71-7.el7.noarch tog-pegasus-libs-2:2.14.1-5.el7.x86_64 libcmpiCppImpl0-2.0.3-5.el7.x86_64"
+    rlPhaseEnd
 
-        # conflict is in libcmpiCppImpl0 which is the second package in the list
-        # make sure tog-pegasus wins
-        compare_with_rpm $EXPORT_DIR filesystem-3.2-21.el7.x86_64.rpm setup-2.8.71-7.el7.noarch.rpm tog-pegasus-libs-2.14.1-5.el7.x86_64.rpm
-        sudo rm -rf $EXPORT_DIR
+    rlPhaseStartCleanup
+        rm -rf $CS_REPO $METADATA_DB *.rpm $EXPORT_DIR
     rlPhaseEnd
 rlJournalEnd
diff --git a/tests/test_import.sh b/tests/test_import.sh
--- a/tests/test_import.sh
+++ b/tests/test_import.sh
@@ -6,17 +6,23 @@
 BDCS="./dist/build/bdcs/bdcs"
 METADATA_DB="./import_metadata.db"
 CENTOS_REPO="centos.repo"
-
+export PATH="./dist/build/bdcs-import:$PATH"
 
 rlJournalStart
     rlPhaseStartSetup
-        rlRun "sqlite3 $METADATA_DB < ../schema.sql"
+        rlRun "sqlite3 $METADATA_DB < ./schema.sql"
     rlPhaseEnd
 
     rlPhaseStartTest "When executed without parameters shows usage"
         output=`$BDCS import | head -n 2 | tail -n 1`
         rlAssertEquals "Usage header as expected" "$output" "Usage: import output.db repo thing [thing ...]"
     rlPhaseEnd
+
+# disable for now b/c still not fixed
+#    rlPhaseStartTest "When importing from URL which gives a 404 exit code should be non-zero"
+#        $BDCS import $METADATA_DB $CENTOS_REPO http://mirror.centos.org/centos/7/os/x86_64/Packages/NON-EXISTING-RPM.rpm
+#        rlAssertNotEquals "On error exit code should not be zero" $? 0
+#    rlPhaseEnd
 
     rlPhaseStartTest "Can import a single RPM from local disk"
         rlRun -t -c "wget http://mirror.centos.org/centos/7/os/x86_64/Packages/setup-2.8.71-7.el7.noarch.rpm"
