[calm - Cygwin server-side packaging maintenance script] branch master, updated. 20250329-13-g5dd2ed8

Jon Turney via Cygwin-apps-cvs <[email protected]> Wed, 25 Jun 2025 18:28:21 +0000 (GMT)
Newsgroups gmane.os.cygwin.cvs.apps
Message-ID <[email protected]>



Diff:
---
 calm/calm.py                                       | 244 ++++++++-------------
 calm/db.py                                         |  16 +-
 calm/hint-migrate.py                               |   2 +-
 calm/mail-inactive-maintainers.py                  |   8 +-
 calm/mksetupini.py                                 |   2 +-
 calm/package.py                                    |  35 ++-
 calm/pkg2html.py                                   | 223 ++++++++-----------
 calm/repology.py                                   |   7 +-
 calm/reports.py                                    |  74 +++----
 calm/untest.py                                     |   2 +-
 calm/uploads.py                                    |  71 +++---
 test/test_calm.py                                  |  15 +-
 test/testdata/htdocs.expected/dirtree.expected     |  74 ++++---
 test/testdata/htdocs.expected/noarch/.htaccess     |   1 +
 .../htdocs.expected/noarch/obs-a/.htaccess         |   2 +
 .../{x86_64 => noarch}/obs-a/obs-a-1.0-1           |   0
 .../htdocs.expected/noarch/obs-b/.htaccess         |   2 +
 .../{x86_64 => noarch}/obs-b/obs-b-1.0-1           |   0
 .../noarch/perl-Net-SMTP-SSL/.htaccess             |   2 +
 .../perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1     |   0
 .../perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1     |   0
 .../perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1     |   0
 .../htdocs.expected/noarch/test-c/.htaccess        |   2 +
 .../{x86_64 => noarch}/test-c/test-c-1.0-1         |   0
 .../htdocs.expected/noarch/test-d/.htaccess        |   2 +
 .../{x86_64 => noarch}/test-d/test-d-1.0.42590-1   |   0
 .../htdocs.expected/noarch/test-e/.htaccess        |   2 +
 .../{x86_64 => noarch}/test-e/test-e-1.0-1         |   0
 test/testdata/htdocs.expected/src/.htaccess        |   1 +
 .../testdata/htdocs.expected/src/arc-src/.htaccess |   2 +
 .../{x86_64 => src}/arc-src/arc-4.32.7-10-src      |   0
 .../htdocs.expected/src/corrupt-src/.htaccess      |   2 +
 .../corrupt-src/corrupt-2.0.0-1-src                |   0
 .../htdocs.expected/src/cygwin-src/.htaccess       |   2 +
 .../{x86_64 => src}/cygwin-src/cygwin-2.2.0-1-src  |   0
 .../{x86_64 => src}/cygwin-src/cygwin-2.2.1-1-src  |   0
 .../cygwin-src/cygwin-2.3.0-0.3-src                |   0
 .../htdocs.expected/src/keychain-src/.htaccess     |   2 +
 .../keychain-src/keychain-2.6.8-1-src              |   0
 .../keychain-src/keychain-2.7.1-1-src              |   0
 .../src/mDNSResponder-src/.htaccess                |   2 +
 .../mDNSResponder-src/mDNSResponder-379.32.1-1-src |   0
 .../htdocs.expected/src/obs-a-src/.htaccess        |   2 +
 .../{x86_64 => src}/obs-a-src/obs-a-1.0-1-src      |   0
 .../htdocs.expected/src/obs-b-src/.htaccess        |   2 +
 .../{x86_64 => src}/obs-b-src/obs-b-1.0-1-src      |   0
 .../htdocs.expected/src/openssh-src/.htaccess      |   2 +
 .../openssh-src/openssh-7.2p2-1-src                |   0
 .../.htaccess                                      |   2 +
 .../per-version-replacement-hint-only-1.0-1-src    |   0
 .../htdocs.expected/src/per-version-src/.htaccess  |   2 +
 .../per-version-src/per-version-4.0-1-src          |   0
 .../per-version-src/per-version-4.8-1-src          |   0
 .../src/perl-Net-SMTP-SSL-src/.htaccess            |   2 +
 .../perl-Net-SMTP-SSL-1.01-1-src                   |   0
 .../perl-Net-SMTP-SSL-1.02-1-src                   |   0
 .../perl-Net-SMTP-SSL-1.03-1-src                   |   0
 .../htdocs.expected/src/rpm-doc-src/.htaccess      |   2 +
 .../{x86_64 => src}/rpm-doc-src/rpm-doc-4.1-2-src  |   0
 .../htdocs.expected/src/staleversion-src/.htaccess |   2 +
 .../staleversion-src/staleversion-240-1-src        |   0
 .../staleversion-src/staleversion-242-0-src        |   0
 .../staleversion-src/staleversion-243-0-src        |   0
 .../staleversion-src/staleversion-250-0-src        |   0
 .../staleversion-src/staleversion-251-0-src        |   0
 .../staleversion-src/staleversion-260-0-src        |   0
 .../htdocs.expected/src/test-c-src/.htaccess       |   2 +
 .../{x86_64 => src}/test-c-src/test-c-1.0-1-src    |   0
 .../htdocs.expected/src/test-d-src/.htaccess       |   2 +
 .../test-d-src/test-d-1.0.42590-1-src              |   0
 .../htdocs.expected/src/test-e-src/.htaccess       |   2 +
 .../{x86_64 => src}/test-e-src/test-e-1.0-1-src    |   0
 .../htdocs.expected/src/testpackage-src/.htaccess  |   2 +
 .../testpackage-src/testpackage-0.1-1-src          |   0
 test/testdata/htdocs.expected/summary/arc-src.html |   2 +-
 test/testdata/htdocs.expected/summary/arc.html     |   0
 .../htdocs.expected/summary/base-cygwin.html       |   0
 .../htdocs.expected/summary/corrupt-src.html       |   2 +-
 test/testdata/htdocs.expected/summary/corrupt.html |   0
 .../htdocs.expected/summary/cygwin-debuginfo.html  |   0
 .../htdocs.expected/summary/cygwin-devel.html      |   0
 .../htdocs.expected/summary/cygwin-src.html        |   6 +-
 test/testdata/htdocs.expected/summary/cygwin.html  |   0
 .../htdocs.expected/summary/keychain-src.html      |   4 +-
 .../testdata/htdocs.expected/summary/keychain.html |   0
 .../htdocs.expected/summary/libdns_sd-devel.html   |   0
 .../htdocs.expected/summary/libdns_sd1.html        |   0
 .../htdocs.expected/summary/mDNSResponder-src.html |   2 +-
 .../htdocs.expected/summary/mDNSResponder.html     |   0
 .../htdocs.expected/summary/obs-a-src.html         |   2 +-
 test/testdata/htdocs.expected/summary/obs-a.html   |   2 +-
 .../htdocs.expected/summary/obs-b-src.html         |   2 +-
 test/testdata/htdocs.expected/summary/obs-b.html   |   2 +-
 .../htdocs.expected/summary/openssh-src.html       |   2 +-
 test/testdata/htdocs.expected/summary/openssh.html |   0
 .../per-version-replacement-hint-only-src.html     |   2 +-
 .../summary/per-version-replacement-hint-only.html |   0
 .../htdocs.expected/summary/per-version-src.html   |   4 +-
 .../htdocs.expected/summary/per-version.html       |   0
 .../summary/perl-Net-SMTP-SSL-src.html             |   6 +-
 .../htdocs.expected/summary/perl-Net-SMTP-SSL.html |   6 +-
 .../htdocs.expected/summary/rpm-doc-src.html       |   2 +-
 test/testdata/htdocs.expected/summary/rpm-doc.html |   0
 .../htdocs.expected/summary/staleversion-src.html  |  12 +-
 .../htdocs.expected/summary/staleversion.html      |   0
 .../htdocs.expected/summary/test-c-src.html        |   2 +-
 test/testdata/htdocs.expected/summary/test-c.html  |   2 +-
 .../htdocs.expected/summary/test-d-src.html        |   2 +-
 test/testdata/htdocs.expected/summary/test-d.html  |   2 +-
 .../htdocs.expected/summary/test-e-src.html        |   2 +-
 test/testdata/htdocs.expected/summary/test-e.html  |   2 +-
 .../htdocs.expected/summary/testpackage-src.html   |   2 +-
 .../htdocs.expected/summary/testpackage.html       |   0
 test/testdata/htdocs.expected/x86/.htaccess        |   1 -
 .../htdocs.expected/x86_64/arc-src/.htaccess       |   2 -
 test/testdata/htdocs.expected/x86_64/arc/.htaccess |   2 +-
 .../htdocs.expected/x86_64/arc/arc-4.32.7-10-src   |  13 --
 .../htdocs.expected/x86_64/base-cygwin/.htaccess   |   2 +-
 .../htdocs.expected/x86_64/corrupt-src/.htaccess   |   2 -
 .../htdocs.expected/x86_64/corrupt/.htaccess       |   2 +-
 .../x86_64/corrupt/corrupt-2.0.0-1-src             |  14 --
 .../x86_64/cygwin-debuginfo/.htaccess              |   2 +-
 .../htdocs.expected/x86_64/cygwin-devel/.htaccess  |   2 +-
 .../htdocs.expected/x86_64/cygwin-src/.htaccess    |   2 -
 .../htdocs.expected/x86_64/cygwin/.htaccess        |   2 +-
 .../x86_64/cygwin/cygwin-2.2.0-1-src               |  13 --
 .../x86_64/cygwin/cygwin-2.2.1-1-src               |  13 --
 .../x86_64/cygwin/cygwin-2.3.0-0.3-src             |  13 --
 .../htdocs.expected/x86_64/keychain-src/.htaccess  |   2 -
 .../htdocs.expected/x86_64/keychain/.htaccess      |   2 +-
 .../x86_64/keychain/keychain-2.6.8-1-src           |  14 --
 .../x86_64/keychain/keychain-2.7.1-1-src           |  16 --
 .../x86_64/libdns_sd-devel/.htaccess               |   2 +-
 .../htdocs.expected/x86_64/libdns_sd1/.htaccess    |   2 +-
 .../x86_64/libtextcat-devel/.htaccess              |   3 -
 .../x86_64/libtextcat-devel/libtextcat-devel-2.2-2 |   7 -
 .../htdocs.expected/x86_64/libtextcat0/.htaccess   |   3 -
 .../x86_64/libtextcat0/libtextcat0-2.2-2           |   7 -
 .../x86_64/mDNSResponder-src/.htaccess             |   2 -
 .../htdocs.expected/x86_64/mDNSResponder/.htaccess |   2 +-
 .../mDNSResponder/mDNSResponder-379.32.1-1-src     |  13 --
 .../testdata/htdocs.expected/x86_64/naim/.htaccess |   3 -
 .../htdocs.expected/x86_64/obs-a-src/.htaccess     |   2 -
 .../htdocs.expected/x86_64/obs-a/.htaccess         |   2 -
 .../htdocs.expected/x86_64/obs-a/obs-a-1.0-1-src   |  12 -
 .../htdocs.expected/x86_64/obs-b-src/.htaccess     |   2 -
 .../htdocs.expected/x86_64/obs-b/.htaccess         |   2 -
 .../htdocs.expected/x86_64/obs-b/obs-b-1.0-1-src   |  12 -
 .../htdocs.expected/x86_64/openssh-src/.htaccess   |   2 -
 .../htdocs.expected/x86_64/openssh/.htaccess       |   2 +-
 .../x86_64/openssh/openssh-7.2p2-1-src             |  13 --
 .../.htaccess                                      |   2 -
 .../per-version-replacement-hint-only/.htaccess    |   2 +-
 .../per-version-replacement-hint-only-1.0-1-src    |  13 --
 .../x86_64/per-version-src/.htaccess               |   2 -
 .../htdocs.expected/x86_64/per-version/.htaccess   |   2 +-
 .../x86_64/per-version/per-version-4.0-1-src       |  13 --
 .../x86_64/per-version/per-version-4.8-1-src       |  13 --
 .../x86_64/perl-Net-SMTP-SSL-src/.htaccess         |   2 -
 .../x86_64/perl-Net-SMTP-SSL/.htaccess             |   2 -
 .../perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1-src |  14 --
 .../perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1-src |  14 --
 .../perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1-src |  14 --
 .../x86_64/proj-debuginfo/.htaccess                |   3 -
 .../x86_64/proj-debuginfo/proj-debuginfo-4.8.0-1   |   7 -
 .../htdocs.expected/x86_64/rpm-doc-src/.htaccess   |   2 -
 .../htdocs.expected/x86_64/rpm-doc/.htaccess       |   2 +-
 .../x86_64/rpm-doc/rpm-doc-4.1-2-src               |  11 -
 .../x86_64/staleversion-src/.htaccess              |   2 -
 .../htdocs.expected/x86_64/staleversion/.htaccess  |   2 +-
 .../x86_64/staleversion/staleversion-240-1-src     |  13 --
 .../x86_64/staleversion/staleversion-242-0-src     |  13 --
 .../x86_64/staleversion/staleversion-243-0-src     |  13 --
 .../x86_64/staleversion/staleversion-250-0-src     |  13 --
 .../x86_64/staleversion/staleversion-251-0-src     |  13 --
 .../x86_64/staleversion/staleversion-260-0-src     |  13 --
 .../htdocs.expected/x86_64/test-c-src/.htaccess    |   2 -
 .../htdocs.expected/x86_64/test-c/.htaccess        |   2 -
 .../htdocs.expected/x86_64/test-c/test-c-1.0-1-src |  12 -
 .../htdocs.expected/x86_64/test-d-src/.htaccess    |   2 -
 .../htdocs.expected/x86_64/test-d/.htaccess        |   2 -
 .../x86_64/test-d/test-d-1.0.42590-1-src           |  12 -
 .../htdocs.expected/x86_64/test-e-src/.htaccess    |   2 -
 .../htdocs.expected/x86_64/test-e/.htaccess        |   2 -
 .../htdocs.expected/x86_64/test-e/test-e-1.0-1-src |  12 -
 .../x86_64/testpackage-src/.htaccess               |   2 -
 .../htdocs.expected/x86_64/testpackage/.htaccess   |   2 +-
 .../x86_64/testpackage/testpackage-0.1-1-src       |  13 --
 test/testdata/process_arch/htdocs.expected         |  58 ++---
 189 files changed, 458 insertions(+), 970 deletions(-)

diff --git a/calm/calm.py b/calm/calm.py
index c8c8a77..5099ecc 100755
--- a/calm/calm.py
+++ b/calm/calm.py
@@ -26,34 +26,33 @@
 #
 
 #
-# for each arch
-# - read and validate packages from release area
-# - stop if there are errors
+# read and validate packages from release area
+# stop if there are errors
 # otherwise,
 # identify and move stale packages
 # for each maintainer
 # - read and validate any package uploads
 # - build a list of files to move and remove
-# - for each arch
-# -- merge package sets
-# -- remove from the package set files which are to be removed
-# -- validate merged package set
-# -- identify stale packages
-# -- process remove list
+# - merge package sets
+# - remove from the package set files which are to be removed
+# - validate merged package set
+# - identify stale packages
+# - process remove list
 # - on failure
-# -- mail maintainer with errors
-# -- empty move list
-# -- discard merged package sets
+# - mail maintainer with errors
+# - empty move list
+# - discard merged package sets
 # - on success
-# -- process move lists
-# -- mail maintainer with movelist
-# -- continue with merged package sets
+# - process move lists
+# - mail maintainer with movelist
+# - continue with merged package sets
 # write package listings
-# write setup.ini file
+# write setup.ini file (for each arch)
 #
 
 import argparse
 import codecs
+import copy
 import functools
 import logging
 import lzma
@@ -102,23 +101,19 @@ class CalmState(object):
 #
 
 def process_relarea(args, state):
-    packages = {}
     error = False
 
-    # read the package list for each arch
-    for arch in common_constants.ARCHES:
-        logging.debug("reading existing packages for arch %s" % (arch))
-        packages[arch], _ = package.read_packages(args.rel_area, arch)
+    # read the package set
+    logging.debug("reading existing packages")
+    packages, _ = package.read_packages(args.rel_area)
 
     state.valid_provides = db.update_package_names(args, packages)
-    for arch in common_constants.ARCHES:
-        state.missing_obsolete[arch] = db.update_missing_obsolete(args, packages, arch)
+    state.missing_obsolete = db.update_missing_obsolete(args, packages)
 
-    # validate the package set for each arch
-    for arch in common_constants.ARCHES:
-        if not package.validate_packages(args, packages[arch], state.valid_provides, state.missing_obsolete[arch]):
-            logging.error("existing %s package set has errors" % (arch))
-            error = True
+    # validate the package set
+    if not package.validate_packages(args, packages, state.valid_provides, state.missing_obsolete):
+        logging.error("existing package set has errors")
+        error = True
 
     if error:
         return None
@@ -126,15 +121,12 @@ def process_relarea(args, state):
     # packages can be stale due to changes made directly in the release
     # area, so first check here if there are any stale packages to vault
     if args.stale:
-        fresh_packages = {}
-        for arch in common_constants.ARCHES:
-            fresh_packages[arch] = package.merge(packages[arch])
+        fresh_packages = copy.deepcopy(packages)
 
         stale_to_vault = remove_stale_packages(args, fresh_packages, state)
-        if stale_to_vault:
-            for arch in common_constants.ARCHES + ['noarch', 'src']:
-                logging.info("vaulting %d old package(s) for arch %s" % (len(stale_to_vault[arch]), arch))
-                stale_to_vault[arch].move_to_vault(args)
+        if stale_to_vault is not None:
+            logging.info("vaulting %d old package(s)" % (len(stale_to_vault)))
+            stale_to_vault.move_to_vault(args)
         else:
             logging.error("error while evaluating stale packages")
             return None
@@ -182,38 +174,33 @@ def process_uploads(args, state):
 
 
 def process_maintainer_uploads(args, state, all_packages, m, basedir, desc, scrub=False, record=None):
-    # for each arch and noarch
-    scan_result = {}
     success = True
-    for arch in common_constants.ARCHES + ['noarch', 'src'] + common_constants.ARCHIVED_ARCHES:
-        logging.debug("reading uploaded arch %s packages from maintainer %s" % (arch, m.name))
+    logging.debug("reading uploaded packages from maintainer %s" % (m.name))
 
-        # read uploads
-        scan_result[arch] = uploads.scan(basedir, m, all_packages, arch, args)
+    # read uploads
+    scan_result = uploads.scan(basedir, m, all_packages, args)
 
-        # remove triggers
-        uploads.remove(args, scan_result[arch].remove_always)
+    # remove triggers
+    uploads.remove(args, scan_result.remove_always)
 
-        # check upload is authorized
-        if not scan_result[arch].error:
-            uploads.auth_check(args, m, scan_result[arch], state.packages)
+    # check upload is authorized
+    if not scan_result.error:
+        uploads.auth_check(args, m, scan_result, state.packages)
 
-        if scan_result[arch].error:
-            logging.error("error while reading uploaded arch %s packages from maintainer %s" % (arch, m.name))
-            success = False
-            continue
+    if scan_result.error:
+        logging.error("error while reading uploadedpackages from maintainer %s" % (m.name))
+        success = False
 
     if success:
         success = _process_maintainer_uploads(scan_result, args, state, all_packages, m, basedir, desc)
 
     # automatically generate announce email if requested
-    if record and success and any([scan_result[a].to_relarea for a in scan_result]):
+    if record and success and scan_result.to_relarea:
         _announce_upload(args, scan_result, m, record)
 
     # remove upload files on success in homedir, always in stagingdir
-    for arch in common_constants.ARCHES + ['noarch', 'src']:
-        if scrub or success:
-            uploads.remove(args, scan_result[arch].remove_success)
+    if scrub or success:
+        uploads.remove(args, scan_result.remove_success)
 
     # clean up any empty directories
     if not args.dryrun:
@@ -233,16 +220,15 @@ def _announce_upload(args, scan_result, maintainer, r):
 
     srcpkg = None
     pkglist = set()
-    for arch in common_constants.ARCHES + ['noarch', 'src']:
-        for po in scan_result[arch].packages.values():
-            if po.kind == package.Kind.source:
-                srcpkg = po
-                assert len(po.versions()) == 1
-                version = list(po.versions())[0]
-                ldesc = po.version_hints[version]['ldesc'].strip('"')
-                test = 'test' in po.version_hints[version]
+    for po in scan_result.packages.values():
+        if po.kind == package.Kind.source:
+            srcpkg = po
+            assert len(po.versions()) == 1
+            version = list(po.versions())[0]
+            ldesc = po.version_hints[version]['ldesc'].strip('"')
+            test = 'test' in po.version_hints[version]
 
-            pkglist.add(po.orig_name)
+        pkglist.add(po.orig_name)
 
     if not srcpkg:
         logging.error("could not locate source package in upload")
@@ -332,25 +318,22 @@ def _process_maintainer_uploads(scan_result, args, state, all_packages, m, based
 
     # if there are no added or removed files for this maintainer, we
     # don't have anything to do
-    if not any([scan_result[a].to_relarea or scan_result[a].to_vault for a in scan_result]):
+    if not (scan_result.to_relarea or scan_result.to_vault):
         logging.debug("nothing to do for maintainer %s" % (name))
         return True
 
-    # for each arch
     merged_packages = {}
     valid = True
-    for arch in common_constants.ARCHES:
-        logging.debug("merging %s package set with uploads from maintainer %s" % (arch, name))
+    logging.debug("merging package set with uploads from maintainer %s" % (name))
 
-        # merge package sets
-        merged_packages[arch] = package.merge(state.packages[arch], scan_result[arch].packages, scan_result['noarch'].packages, scan_result['src'].packages)
-        if not merged_packages[arch]:
-            logging.error("error while merging uploaded %s packages for %s" % (arch, name))
-            valid = False
-            break
+    # merge package sets
+    merged_packages = package.merge(state.packages, scan_result.packages)
+    if not merged_packages:
+        logging.error("error while merging uploaded packages for %s" % (name))
+        valid = False
 
-        # remove files which are to be removed
-        scan_result[arch].to_vault.map(lambda p, f: package.delete(merged_packages[arch], p, f))
+    # remove files which are to be removed
+    scan_result.to_vault.map(lambda p, f: package.delete(merged_packages, p, f))
 
     # if an error occurred ...
     if not valid:
@@ -359,15 +342,13 @@ def _process_maintainer_uploads(scan_result, args, state, all_packages, m, based
 
     # validate the package set
     state.valid_provides = db.update_package_names(args, merged_packages)
-    for arch in common_constants.ARCHES:
-        logging.debug("validating merged %s package set for maintainer %s" % (arch, name))
-        if not package.validate_packages(args, merged_packages[arch], state.valid_provides, state.missing_obsolete):
-            logging.error("error while validating merged %s packages for %s" % (arch, name))
-            valid = False
+    logging.debug("validating merged package set for maintainer %s" % (name))
+    if not package.validate_packages(args, merged_packages, state.valid_provides, state.missing_obsolete):
+        logging.error("error while validating merged packages for %s" % (name))
+        valid = False
 
     # issue any 'upload time only' validation warnings
-    for arch in common_constants.ARCHES:
-        package.packages_warnings(args, merged_packages[arch], scan_result[arch].packages, scan_result['noarch'].packages, scan_result['src'].packages)
+    package.packages_warnings(args, merged_packages, scan_result.packages)
 
     # if an error occurred ...
     if not valid:
@@ -380,17 +361,15 @@ def _process_maintainer_uploads(scan_result, args, state, all_packages, m, based
         stale_to_vault = remove_stale_packages(args, merged_packages, state)
 
         # if an error occurred ...
-        if not stale_to_vault:
+        if stale_to_vault is None:
             # ... discard move list and merged_packages
             logging.error("error while evaluating stale packages for %s" % (name))
             return False
 
     # check for conflicting movelists
-    conflicts = False
-    for arch in common_constants.ARCHES + ['noarch', 'src']:
-        conflicts = conflicts or report_movelist_conflicts(scan_result[arch].to_relarea, scan_result[arch].to_vault, "manually")
-        if args.stale:
-            conflicts = conflicts or report_movelist_conflicts(scan_result[arch].to_relarea, stale_to_vault[arch], "automatically")
+    conflicts = report_movelist_conflicts(scan_result.to_relarea, scan_result.to_vault, "manually")
+    if args.stale:
+        conflicts = conflicts or report_movelist_conflicts(scan_result.to_relarea, stale_to_vault, "automatically")
 
     # if an error occurred ...
     if conflicts:
@@ -398,40 +377,30 @@ def _process_maintainer_uploads(scan_result, args, state, all_packages, m, based
         logging.error("error while validating movelists for %s" % (name))
         return False
 
-    # for each arch and noarch
-    for arch in common_constants.ARCHES + ['noarch', 'src']:
-        logging.debug("moving %s packages for maintainer %s" % (arch, name))
+    # process the move lists
+    logging.debug("moving packages for maintainer %s" % (name))
+    if scan_result.to_vault:
+        logging.info("vaulting %d package(s), by request" % (len(scan_result.to_vault)))
+    scan_result.to_vault.move_to_vault(args)
 
-        # process the move lists
-        if scan_result[arch].to_vault:
-            logging.info("vaulting %d package(s) for arch %s, by request" % (len(scan_result[arch].to_vault), arch))
-        scan_result[arch].to_vault.move_to_vault(args)
+    if scan_result.to_relarea:
+        logging.info("adding %d package(s)" % (len(scan_result.to_relarea)))
+    scan_result.to_relarea.move_to_relarea(m, args, desc)
 
-        if scan_result[arch].to_relarea:
-            logging.info("adding %d package(s) for arch %s" % (len(scan_result[arch].to_relarea), arch))
-        scan_result[arch].to_relarea.move_to_relarea(m, args, desc)
+    # XXX: Note that there seems to be a separate process, not run
+    # from cygwin-admin's crontab, which changes the ownership of
+    # files in the release area to cyguser:cygwin
 
-        # XXX: Note that there seems to be a separate process, not run
-        # from cygwin-admin's crontab, which changes the ownership of
-        # files in the release area to cyguser:cygwin
-
-    # for each arch
     if args.stale:
-        for arch in common_constants.ARCHES + ['noarch', 'src']:
-            if stale_to_vault[arch]:
-                logging.info("vaulting %d old package(s) for arch %s" % (len(stale_to_vault[arch]), arch))
-                stale_to_vault[arch].move_to_vault(args)
+        if stale_to_vault:
+            logging.info("vaulting %d old package(s)" % (len(stale_to_vault)))
+            stale_to_vault.move_to_vault(args)
 
-    # for each arch
-    for arch in common_constants.ARCHES:
-        # use merged package list
-        state.packages[arch] = merged_packages[arch]
+    # use merged package list
+    state.packages = merged_packages
 
     # report what we've done to irc
-    added = []
-    for arch in common_constants.ARCHES + ['noarch', 'src']:
-        added.append('%d (%s)' % (len(scan_result[arch].packages), arch))
-    msg = "added %s packages from maintainer %s" % (' + '.join(added), name)
+    msg = "added %s packages from maintainer %s" % (len(scan_result.packages), name)
     logging.debug(msg)
     irk.irk("calm %s" % msg)
 
@@ -462,23 +431,18 @@ def process(args, state):
 #
 
 def remove_stale_packages(args, packages, state):
-    to_vault = {}
-    to_vault['noarch'] = MoveList()
-    to_vault['src'] = MoveList()
-
     vault_requests = db.vault_requests(args)
 
-    for arch in common_constants.ARCHES:
-        logging.debug("checking for stale packages for arch %s" % (arch))
+    logging.debug("checking for stale packages")
 
-        # find stale packages
-        to_vault[arch] = package.stale_packages(packages[arch], vault_requests)
+    # find stale packages
+    to_vault = package.stale_packages(packages, vault_requests)
 
-        # remove stale packages from package set
-        to_vault[arch].map(lambda p, f: package.delete(packages[arch], p, f))
+    # remove stale packages from package set
+    to_vault.map(lambda p, f: package.delete(packages, p, f))
 
     # if there are no stale packages, we don't have anything to do
-    if not any([to_vault[a] for a in to_vault]):
+    if not to_vault:
         logging.debug("nothing is stale")
         return to_vault
 
@@ -486,33 +450,13 @@ def remove_stale_packages(args, packages, state):
     # (this shouldn't fail, but we check just to sure...)
     error = False
     state.valid_provides = db.update_package_names(args, packages)
-    for arch in common_constants.ARCHES:
-        if not package.validate_packages(args, packages[arch], state.valid_provides, state.missing_obsolete):
-            logging.error("%s package set has errors after removing stale packages" % arch)
-            error = True
+    if not package.validate_packages(args, packages, state.valid_provides, state.missing_obsolete):
+        logging.error("package set has errors after removing stale packages")
+        error = True
 
     if error:
         return None
 
-    # since noarch and src packages are included in the package set for both
-    # arch, we will build (hopefully) identical move lists for those packages
-    # for each arch.
-    #
-    # de-duplicate these package moves, as rather awkward workaround for that
-    moved_list = set()
-
-    def dedup(path, f):
-        for prefix in ['noarch', 'src']:
-            if path.startswith(prefix):
-                to_vault[prefix].add(path, f)
-                moved_list.add(path)
-
-    to_vault[common_constants.ARCHES[0]].map(dedup)
-
-    for path in moved_list:
-        for arch in common_constants.ARCHES:
-            to_vault[arch].remove(path)
-
     return to_vault
 
 
@@ -607,7 +551,7 @@ def do_output(args, state):
             changed = False
 
             # write setup.ini
-            package.write_setup_ini(args, state.packages[arch], arch)
+            package.write_setup_ini(args, state.packages, arch)
 
             # make it world-readable, if we can
             try:
diff --git a/calm/db.py b/calm/db.py
index 3c2f761..cf2051f 100644
--- a/calm/db.py
+++ b/calm/db.py
@@ -70,9 +70,7 @@ def connect(args):
 # ones which aren't in the set of names for current package
 #
 def update_package_names(args, packages):
-    current_names = set()
-    for arch in packages:
-        current_names.update(packages[arch])
+    current_names = set(packages.keys())
 
     with connect(args) as conn:
         conn.row_factory = sqlite3.Row
@@ -122,25 +120,27 @@ def vault_request_add(args, p, v):
 # this accumulates missing_obsoletes data for packages, so we will remember it
 # even after the obsoleted package has been removed
 #
-def update_missing_obsolete(args, packages, arch):
+# N.B. missing_obsolete data only exists for historic, and should be only
+# applied to, x86_64 packages
+def update_missing_obsolete(args, packages):
     data = {}
     with connect(args) as conn:
         conn.row_factory = sqlite3.Row
 
         # read
-        cur = conn.execute("SELECT name, replaces FROM missing_obsolete WHERE arch = ?", (arch,))
+        cur = conn.execute("SELECT name, replaces FROM missing_obsolete")
         for row in cur.fetchall():
             data[row['name']] = set(row['replaces'].split())
 
         # update missing obsoletes data
-        missing_obsolete = package.upgrade_oldstyle_obsoletes(packages[arch], data.copy())
+        missing_obsolete = package.upgrade_oldstyle_obsoletes(packages, data.copy())
 
         # update
         for n, r in missing_obsolete.items():
             if n not in data:
-                conn.execute('INSERT INTO missing_obsolete (name, arch, replaces) VALUES (?, ? , ?)', (n, arch, ' '.join(r)))
+                conn.execute('INSERT INTO missing_obsolete (name, arch, replaces) VALUES (?, ? , ?)', (n, 'x8_64', ' '.join(r)))
             else:
-                conn.execute('UPDATE missing_obsolete SET replaces = ? WHERE name = ? AND arch = ?', (' '.join(r), n, arch))
+                conn.execute('UPDATE missing_obsolete SET replaces = ? WHERE name = ? AND arch = ?', (' '.join(r), n, 'x86_64'))
 
     return missing_obsolete
 
diff --git a/calm/hint-migrate.py b/calm/hint-migrate.py
index 43c5ae9..8b33658 100644
--- a/calm/hint-migrate.py
+++ b/calm/hint-migrate.py
@@ -39,7 +39,7 @@ from . import hint
 
 
 def hint_migrate(args):
-    for arch in common_constants.ARCHES + ['noarch']:
+    for arch in common_constants.ARCHES + ['noarch', 'src']:
         basedir = os.path.join(args.rel_area, arch, 'release')
 
         for (dirpath, _subdirs, files) in os.walk(basedir):
diff --git a/calm/mail-inactive-maintainers.py b/calm/mail-inactive-maintainers.py
index fb9a931..5ec4934 100644
--- a/calm/mail-inactive-maintainers.py
+++ b/calm/mail-inactive-maintainers.py
@@ -63,10 +63,8 @@ For further assistance, please contact us via email at <[email protected]>
 def main(args):
     logging.getLogger().setLevel(logging.WARNING)
 
-    packages = {}
-    for arch in common_constants.ARCHES:
-        logging.debug("reading existing packages for arch %s" % (arch))
-        packages[arch], _ = package.read_packages(args.relarea, arch)
+    logging.debug("reading existing packages")
+    packages, _ = package.read_packages(args.relarea)
 
     activity_list = reports.maintainer_activity(args, packages)
 
@@ -83,7 +81,7 @@ def main(args):
 
         if last_activity < threshold:
             logging.info('%s %s %s %s', a.name, a.email, pkg2html.tsformat(last_activity), a.pkgs)
-            pkg_list = [packages[arch][p].orig_name for p in a.pkgs]
+            pkg_list = [packages[p].orig_name for p in a.pkgs]
 
             hdr = {}
             hdr['To'] = ','.join(a.email)
diff --git a/calm/mksetupini.py b/calm/mksetupini.py
index 70eee22..8b9888d 100755
--- a/calm/mksetupini.py
+++ b/calm/mksetupini.py
@@ -48,7 +48,7 @@ except ImportError:
 #
 def do_main(args):
     # build package list
-    packages, error = package.read_packages(args.rel_area, args.arch)
+    packages, error = package.read_packages(args.rel_area)
 
     if error and not args.ignore_errors:
         logging.error("errors reading package set, not writing setup.ini")
diff --git a/calm/package.py b/calm/package.py
index 8c523f3..50ed906 100755
--- a/calm/package.py
+++ b/calm/package.py
@@ -158,13 +158,13 @@ class Hint(object):
 #
 # read a packages from a directory hierarchy
 #
-def read_packages(rel_area, arch):
+def read_packages(rel_area):
     result = False
 
     # first collect all package files
-    # <arch>/ noarch/ and src/ directories are considered
+    # all <arch>/, noarch/ and src/ directories are considered
     collected = {}
-    for root in ['noarch', 'src', arch]:
+    for root in ['noarch', 'src'] + common_constants.ARCHES:
         releasedir = os.path.join(rel_area, root)
 
         for (dirpath, _subdirs, files) in os.walk(releasedir, followlinks=True):
@@ -343,7 +343,7 @@ def clean_hints(p, hints, warnings):
 def collect_files_package_dir(collected, basedir, dirpath, files):
     relpath = os.path.relpath(dirpath, basedir)
 
-    # skip over arch/release/ directories
+    # skip over <arch>/release/ directories
     if relpath.count(os.sep) < 2:
         return
 
@@ -1299,6 +1299,9 @@ def write_setup_ini(args, packages, arch):
             if po.not_for_output:
                 continue
 
+            # XXX: TODO for multiarch: filter version list where package exists
+            # for this arch (skip this package if it ends up empty)
+
             # write package data
             print("\n@ %s" % pn, file=f)
 
@@ -1486,25 +1489,16 @@ def _find_build_recipe_file(args, pn):
 # write a json summary of packages
 #
 def write_repo_json(args, packages, f):
-    package_list = set()
-    for arch in packages:
-        package_list.update(packages[arch])
-
     pkg_maintainers = maintainers.pkg_list(args.pkglist)
 
     pl = []
-    for pn in sorted(package_list):
-        po = None
-        arches = []
-        for arch in common_constants.ARCHES:
-            if pn in packages[arch]:
-                po = packages[arch][pn]
-                arches.append(arch)
+    for pn in sorted(packages):
+        po = packages[pn]
+        arches = common_constants.ARCHES  # XXX: multiarch TODO: set of arches which have this package
 
         def package(p):
-            for arch in common_constants.ARCHES:
-                if p in packages[arch]:
-                    return packages[arch][p]
+            if p in packages:
+                return packages[p]
 
             # will lead to AttributeError as has no version_hints
             return None
@@ -1884,6 +1878,5 @@ def stale_packages(packages, vault_requests):
 #
 
 if __name__ == "__main__":
-    for arch in common_constants.ARCHES:
-        packages, _ = read_packages(common_constants.FTP, arch)
-        print("arch %s has %d packages" % (arch, len(packages)))
+    packages, _ = read_packages(common_constants.FTP)
+    print("relarea has %d packages" % (len(packages)))
diff --git a/calm/pkg2html.py b/calm/pkg2html.py
index 8c43c3f..1cca3e8 100755
--- a/calm/pkg2html.py
+++ b/calm/pkg2html.py
@@ -103,27 +103,6 @@ def ldesc(po, bv):
     return header
 
 
-#
-# try hard to find a package object for package p
-#
-def arch_package(packages, p):
-    for arch in common_constants.ARCHES:
-        if p in packages[arch]:
-            return packages[arch][p]
-    return None
-
-
-#
-# build a dict of the arches which contain package p
-#
-def arch_packages(packages, p):
-    result = {}
-    for arch in common_constants.ARCHES:
-        if p in packages[arch]:
-            result[arch] = packages[arch][p]
-    return result
-
-
 #
 # ensure a directory exists
 #
@@ -151,12 +130,8 @@ def tsformat(ts):
 #
 
 def update_package_listings(args, packages):
-    package_list = set()
     update_summary = set()
-
-    for arch in packages:
-        update_summary.update(write_arch_listing(args, packages[arch], arch))
-        package_list.update(packages[arch])
+    update_summary.update(write_package_listings(args, packages))
 
     summaries = os.path.join(args.htdocs, 'summary')
     ensure_dir_exists(args, summaries)
@@ -167,14 +142,14 @@ def update_package_listings(args, packages):
 
     def linkify_package(pkg):
         p = re.sub(r'(.*)\s+\(.*\)', r'\1', pkg)
-        if p in package_list:
-            pn = arch_package(packages, p).orig_name
+        if p in packages:
+            pn = packages[p].orig_name
             text = re.sub(re.escape(p), pn, pkg)
             return '<a href="%s.html">%s</a>' % (p, text)
         logging.debug('package linkification failed for %s' % p)
         return p
 
-    for p in package_list:
+    for p in packages:
         #
         # write package summary
         #
@@ -187,11 +162,7 @@ def update_package_listings(args, packages):
         if summary in toremove:
             toremove.remove(summary)
 
-        pos = arch_packages(packages, p)
-        if not pos:
-            continue
-
-        po = next(iter(pos.values()))
+        po = packages[p]
         bv = po.best_version
 
         # update summary if:
@@ -256,6 +227,12 @@ def update_package_listings(args, packages):
                         }
 
                     for key in details:
+                        # XXX: multiarch TODO:
+                        # access to per-arch version_hints ???
+                        pos = {}
+                        for arch in common_constants.ARCHES:
+                            pos[arch] = po
+
                         # make the union of the package list for this detail
                         # across arches, and then annotate any items which don't
                         # appear for all arches
@@ -286,9 +263,7 @@ def update_package_listings(args, packages):
                     if po.kind == package.Kind.source:
                         es = p
 
-                        install_packages = set()
-                        for arch in pos:
-                            install_packages.update(pos[arch].is_used_by)
+                        install_packages = po.is_used_by
                         details_table['install package(s)'] = ', '.join([linkify_package(p) for p in sorted(install_packages)])
 
                         homepage = po.version_hints[po.best_version].get('homepage', None)
@@ -302,8 +277,9 @@ def update_package_listings(args, packages):
                         es = po.srcpackage(bv)
                         details_table['source package'] = linkify_package(es)
 
-                    es_po = arch_package(packages, es)
-                    if not es_po:
+                    if es in packages:
+                        es_po = packages[es]
+                    else:
                         es_po = po
 
                     m_pn = es_po.orig_name
@@ -358,25 +334,24 @@ def update_package_listings(args, packages):
 
                     # output package versions table
                     versions_table = []
-                    for arch in sorted(packages):
-                        if p in packages[arch]:
-
-                            def tar_line(pn, p, v, arch):
-                                item = types.SimpleNamespace()
-                                item.version = v
-                                item.size = int(math.ceil(p.tar(v).size / 1024))
-                                if p.kind == package.Kind.binary:
-                                    target = "%s-%s" % (p.orig_name, v)
-                                else:
-                                    target = "%s-%s-src" % (p.orig_name, v)
-                                item.link = "../%s/%s/%s" % (arch, pn, target)
-                                item.status = 'test' if 'test' in p.version_hints[v] else 'stable'
-                                item.ts = tsformat(p.tar(v).mtime)
-                                item.arch = p.tar(v).arch
-                                return item
 
-                            for version in packages[arch][p].versions():
-                                versions_table.append(tar_line(p, packages[arch][p], version, arch))
+                    def tar_line(pn, p, v):
+                        item = types.SimpleNamespace()
+                        item.version = v
+                        item.size = int(math.ceil(p.tar(v).size / 1024))
+                        if p.kind == package.Kind.binary:
+                            target = "%s-%s" % (p.orig_name, v)
+                        else:
+                            target = "%s-%s-src" % (p.orig_name, v)
+                        item.link = "../%s/%s/%s" % (p.tar(v).arch, pn, target)
+                        item.status = 'test' if 'test' in p.version_hints[v] else 'stable'
+                        item.ts = tsformat(p.tar(v).mtime)
+                        item.arch = p.tar(v).arch
+                        return item
+
+                    # XXX: multiarch TODO: iterate over all versions and arches per version?
+                    for version in packages[p].versions():
+                        versions_table.append(tar_line(p, packages[p], version))
 
                     print('<table class="pkgtable">', file=f)
                     print('<tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>', file=f)
@@ -417,19 +392,18 @@ def write_packages_inc(args, packages, name, kind, includer):
         with utils.open_amifc(packages_inc, cb=functools.partial(touch_including, package_list)) as index:
             os.fchmod(index.fileno(), 0o644)
 
-            # This list contains all packages in any arch. Source packages
-            # appear under their original package name.
+            # Install package list contains all packages in any arch.
+            # Source package list appear under their original package name.
             package_list = {}
-            for arch in packages:
-                for p in packages[arch]:
-                    if p.endswith('-debuginfo'):
-                        continue
+            for p in packages:
+                if p.endswith('-debuginfo'):
+                    continue
 
-                    if packages[arch][p].not_for_output:
-                        continue
+                if packages[p].not_for_output:
+                    continue
 
-                    if packages[arch][p].kind == kind:
-                        package_list[packages[arch][p].orig_name] = p
+                if packages[p].kind == kind:
+                    package_list[packages[p].orig_name] = p
 
             jumplist = set()
             for k in package_list:
@@ -450,10 +424,11 @@ def write_packages_inc(args, packages, name, kind, includer):
             for k in sorted(package_list, key=package.sort_key):
                 p = package_list[k]
 
-                po = arch_package(packages, p)
-                if not po:
+                if p not in packages:
                     continue
 
+                po = packages[p]
+
                 bv = po.best_version
                 header = sdesc(po, bv)
 
@@ -526,77 +501,83 @@ def write_doc_inc(args):
             print('</div>', file=index)
 
 
-def write_arch_listing(args, packages, arch):
+def write_package_listings(args, packages):
     update_summary = set()
     update_doc_inc = False
-    base = os.path.join(args.htdocs, arch)
-    ensure_dir_exists(args, base)
+
+    # collect together a list of all the listing files
+    #
+    # (this has to be done at this level, since we want to remove listings
+    # corresponding to removed packages)
+    toremove = set()
 
     #
     # write base directory .htaccess, if needed
     #
     # force trying to access the base directory to redirect to the package list
-    # page, as having the server index this directory containing lots of
+    # page (as having the server index this directory containing lots of
     # subdirectories makes this URL very expensive to serve if someone stumbles
     # onto it by accident)
     #
+    for arch in common_constants.ARCHES + ['noarch', 'src']:
+        base = os.path.join(args.htdocs, arch)
+        ensure_dir_exists(args, base)
 
-    htaccess = os.path.join(base, '.htaccess')
-    if not os.path.exists(htaccess) or args.force:
-        if not args.dryrun:
-            with utils.open_amifc(htaccess) as f:
+        htaccess = os.path.join(base, '.htaccess')
+        if not os.path.exists(htaccess) or args.force:
+            if not args.dryrun:
+                with utils.open_amifc(htaccess) as f:
 
-                print('Redirect temp /packages/%s/index.html https://cygwin.com/packages/package_list.html' % (arch),
-                      file=f)
+                    print('Redirect temp /packages/%s/index.html https://cygwin.com/packages/package_list.html' % (arch),
+                          file=f)
 
-    toremove = glob.glob(os.path.join(base, '*', '*')) + glob.glob(os.path.join(base, '*', '.*'))
+        toremove.update(glob.glob(os.path.join(base, '*', '*')))
+        toremove.update(glob.glob(os.path.join(base, '*', '.*')))
 
     for p in packages:
 
-        dirpath = os.path.join(base, p)
-        ensure_dir_exists(args, dirpath)
+        def check_directory_setup(dirpath):
+            ensure_dir_exists(args, dirpath)
 
-        #
-        # write .htaccess if needed
-        #
-
-        htaccess = os.path.join(dirpath, '.htaccess')
-        if not os.path.exists(htaccess):
-            if not args.dryrun or args.force:
-                with utils.open_amifc(htaccess) as f:
-                    # We used to allow access to the directory listing as a
-                    # crude way of listing the versions of the package available
-                    # for which file lists were available. Redirect that index
-                    # page to the summary page, which now has that information
-                    # (and more).
-                    print('RedirectMatch temp /packages/%s/%s/$ /packages/summary/%s.html' % (arch, p, p),
-                          file=f)
-
-                    # listing files don't have the extension, but are html
-                    print('ForceType text/html', file=f)
+            #
+            # write .htaccess if needed
+            #
+            htaccess = os.path.join(dirpath, '.htaccess')
+            if not os.path.exists(htaccess):
+                if not args.dryrun or args.force:
+                    with utils.open_amifc(htaccess) as f:
+                        # We used to allow access to the directory listing as a
+                        # crude way of listing the versions of the package available
+                        # for which file lists were available. Redirect that index
+                        # page to the summary page, which now has that information
+                        # (and more).
+                        print('RedirectMatch temp /packages/%s/%s/$ /packages/summary/%s.html' % (arch, p, p),
+                              file=f)
+
+                        # listing files don't have the extension, but are html
+                        print('ForceType text/html', file=f)
 
-        # this file should exist, so remove from the toremove list
-        if htaccess in toremove:
-            toremove.remove(htaccess)
+            # this file should exist, so remove from the toremove list
+            if htaccess in toremove:
+                toremove.remove(htaccess)
 
         #
         # for each tarfile, write tarfile listing
         #
-        if os.path.exists(dirpath):
-            listings = os.listdir(dirpath)
-            listings.remove('.htaccess')
-        else:
-            listings = []
 
+        # XXX: multiarch TODO: iterate over all versions and arches per version?
         for v in sorted(packages[p].versions(), key=lambda v: SetupVersion(v)):
             to = packages[p].tar(v)
 
+            dirpath = os.path.join(args.htdocs, to.arch, p)
             # the way this filename is built is pretty arbitrary, but is linked
             # to from the summary page, and package-grep relies on its knowledge
             # of the scheme when producing its output
             fn = packages[p].orig_name + '-' + v + ('-src' if packages[p].kind == package.Kind.source else '')
             listing = os.path.join(dirpath, fn)
 
+            check_directory_setup(dirpath)
+
             # ... if it doesn't already exist, or --force --force
             if not os.path.exists(listing) or (args.force > 1):
 
@@ -677,27 +658,21 @@ def write_arch_listing(args, packages, arch):
             if listing in toremove:
                 toremove.remove(listing)
 
-            if fn in listings:
-                listings.remove(fn)
-
-        # some versions remain on toremove list, and will be removed, so summary
-        # needs updating
-        if listings:
-            update_summary.add(p)
-
     #
     # remove any remaining files for which there was no corresponding package
     #
-
-    for r in toremove:
+    for r in sorted(toremove):
         logging.debug('rm %s' % r)
         if not args.dryrun:
+            # if we end up with '<arch>/packagename/someversion' left in the
+            # toremove list, packagename needs a summary update
+            p = r.split(os.path.sep)[1]
+            update_summary.add(p)
+
+            # remove the file
             os.unlink(r)
 
-            #
             # remove any directories which are now empty
-            #
-
             dirpath = os.path.dirname(r)
             if len(os.listdir(dirpath)) == 0:
                 logging.debug('rmdir %s' % dirpath)
@@ -727,9 +702,5 @@ if __name__ == "__main__":
 
     logging.basicConfig(format=os.path.basename(sys.argv[0]) + ': %(message)s')
 
-#    packages = {}
-#    for arch in common_constants.ARCHES:
-#        packages[arch], _ = package.read_packages(args.rel_area, arch)
-#
-#    update_package_listings(args, packages)
+    packages, _ = package.read_packages(args.rel_area)
     write_doc_inc(args)
diff --git a/calm/repology.py b/calm/repology.py
index f2a6f60..cc374a8 100644
--- a/calm/repology.py
+++ b/calm/repology.py
@@ -182,9 +182,8 @@ def annotate_packages(args, packages):
 
     for pn in last_data:
         spn = pn + '-src'
-        for arch in packages:
-            if spn in packages[arch]:
-                packages[arch][spn].upstream_version = seqmatch(packages[arch][spn].best_version, last_data[pn].upstream_version)
-                packages[arch][spn].repology_project_name = last_data[pn].repology_project_name
+        if spn in packages:
+            packages[spn].upstream_version = seqmatch(packages[spn].best_version, last_data[pn].upstream_version)
+            packages[spn].repology_project_name = last_data[pn].repology_project_name
 
     last_check = time.time()
diff --git a/calm/reports.py b/calm/reports.py
index efd1b9b..b8b4559 100644
--- a/calm/reports.py
+++ b/calm/reports.py
@@ -100,10 +100,8 @@ def maintainer_packages(args, packages, maintainer, reportlist):
 
     um_list = []
 
-    arch = 'x86_64'
-    # XXX: look into how we can make this 'src', after x86 is dropped
-    for p in packages[arch]:
-        po = packages[arch][p]
+    for p in packages:
+        po = packages[p]
 
         if po.kind != package.Kind.source:
             continue
@@ -131,8 +129,8 @@ def maintainer_packages(args, packages, maintainer, reportlist):
         rdepends = set()
         build_rdepends = set()
         for subp in po.is_used_by:
-            rdepends.update(packages[arch][subp].rdepends)
-            build_rdepends.update(packages[arch][subp].build_rdepends)
+            rdepends.update(packages[subp].rdepends)
+            build_rdepends.update(packages[subp].build_rdepends)
 
         up = types.SimpleNamespace()
         up.pn = p
@@ -184,10 +182,8 @@ def maintainer_packages(args, packages, maintainer, reportlist):
 def deprecated(args, packages, reportlist):
     dep_list = []
 
-    arch = 'x86_64'
-    # XXX: look into how we can make this 'src', after x86 is dropped
-    for p in packages[arch]:
-        po = packages[arch][p]
+    for p in packages:
+        po = packages[p]
 
         if po.kind != package.Kind.binary:
             continue
@@ -203,7 +199,7 @@ def deprecated(args, packages, reportlist):
         if not es:
             continue
 
-        if packages[arch][es].best_version == bv:
+        if packages[es].best_version == bv:
             continue
 
         if po.tar(bv).is_empty:
@@ -220,12 +216,12 @@ def deprecated(args, packages, reportlist):
         depp.rdepends = []
         for d in po.rdepends:
             # have a different source package
-            bv = packages[arch][d].best_version
-            if packages[arch][d].srcpackage(bv) == es:
+            bv = packages[d].best_version
+            if packages[d].srcpackage(bv) == es:
                 continue
 
             # current version has the dependency of interest
-            dpl = package.deplist_without_versions(packages[arch][d].version_hints[bv]['depends'])
+            dpl = package.deplist_without_versions(packages[d].version_hints[bv]['depends'])
             if p not in dpl:
                 continue
 
@@ -245,10 +241,10 @@ def deprecated(args, packages, reportlist):
         print('<tr><th>package</th><th>srcpackage</th><th>version</th><th>timestamp</th></tr>', file=body)
 
         for r in sorted(depp.rdepends):
-            po = packages[arch][r]
+            po = packages[r]
             bv = po.best_version
             spn = po.srcpackage(bv)
-            spo = packages[arch][spn]
+            spo = packages[spn]
 
             print('<tr><td>%s</td><td>%s</td><td>%s</td><td>%s</td></tr>' %
                   (linkify(r, po), linkify(spn, spo), bv, pkg2html.tsformat(po.tar(bv).mtime)), file=body)
@@ -286,10 +282,8 @@ def deprecated(args, packages, reportlist):
 def unstable(args, packages, reportlist):
     unstable_list = []
 
-    arch = 'x86_64'
-    # XXX: look into how we can make this 'src', after x86 is dropped
-    for p in packages[arch]:
-        po = packages[arch][p]
+    for p in packages:
+        po = packages[p]
 
         if po.kind != package.Kind.source:
             continue
@@ -327,9 +321,6 @@ def unstable(args, packages, reportlist):
 def maintainer_activity(args, packages):
     activity_list = []
 
-    arch = 'x86_64'
-    # XXX: look into how we can make this 'src', after x86 is dropped
-
     ml = maintainers.maintainer_list(args)
     for m in ml.values():
         if m.name == 'ORPHANED':
@@ -351,10 +342,10 @@ def maintainer_activity(args, packages):
 
             pn = p.data + '-src'
             # do something reasonable for sourceless packages
-            if pn not in packages[arch]:
+            if pn not in packages:
                 pn = p.data
 
-            po = packages[arch].get(pn, None)
+            po = packages.get(pn, None)
             if po:
                 pkgs.append(pn)
 
@@ -383,7 +374,6 @@ def maintainer_activity(args, packages):
 # produce a report on maintainer (in)activity
 #
 def maintainer_activity_report(args, packages, reportlist):
-    arch = 'x86_64'
     activity_list = maintainer_activity(args, packages)
 
     body = io.StringIO()
@@ -394,7 +384,7 @@ def maintainer_activity_report(args, packages, reportlist):
 
     for a in sorted(activity_list, key=lambda i: max(i.last_seen, i.last_package)):
         def pkg_details(pkgs):
-            return '<details><summary>%d</summary>%s</details>' % (len(pkgs), ', '.join(linkify(p, packages[arch][p]) for p in pkgs))
+            return '<details><summary>%d</summary>%s</details>' % (len(pkgs), ', '.join(linkify(p, packages[p]) for p in pkgs))
 
         def maintainer_link(m):
             return '<a href="%s">%s</a>' % (filenameify(m), m)
@@ -413,10 +403,7 @@ def maintainer_activity_report(args, packages, reportlist):
 def provides_rebuild(args, packages, fn, provide_package, reportlist):
     pr_list = []
 
-    arch = 'x86_64'
-    # XXX: look into how we can change this, after x86 is dropped
-
-    pp_package = packages[arch].get(provide_package, None)
+    pp_package = packages.get(provide_package, None)
     pp_provide = None
 
     if pp_package:
@@ -424,11 +411,11 @@ def provides_rebuild(args, packages, fn, provide_package, reportlist):
         pp_provide = pp_package.version_hints[pp_bv]['provides'][0]
         pp_provide_base = re.sub(r'\d+$', '', pp_provide)
 
-        for p in packages[arch]:
-            po = packages[arch][p]
+        for p in packages:
+            po = packages[p]
             bv = po.best_version
 
-            depends = packages[arch][p].version_hints[bv]['depends']
+            depends = packages[p].version_hints[bv]['depends']
             depends = package.deplist_without_versions(depends)
 
             for d in depends:
@@ -446,7 +433,7 @@ def provides_rebuild(args, packages, fn, provide_package, reportlist):
                 pr.pn = p
                 pr.po = po
                 pr.spn = po.srcpackage(bv)
-                pr.spo = packages[arch][pr.spn]
+                pr.spo = packages[pr.spn]
                 pr.depends = d
                 pr.bv = bv
 
@@ -473,11 +460,8 @@ def provides_rebuild(args, packages, fn, provide_package, reportlist):
 def python_rebuild(args, packages, fn, reportlist):
     pr_list = []
 
-    # XXX: look into how we can change this, after x86 is dropped
-    arch = 'x86_64'
-
     # assume that python3 depends only on the latest python3n package
-    py_package = packages[arch].get('python3', None)
+    py_package = packages.get('python3', None)
     if not py_package:
         return
 
@@ -485,14 +469,14 @@ def python_rebuild(args, packages, fn, reportlist):
 
     modules = {}
 
-    for p in packages[arch]:
-        po = packages[arch][p]
+    for p in packages:
+        po = packages[p]
         bv = po.best_version
 
         if po.obsoleted_by:
             continue
 
-        depends = packages[arch][p].version_hints[bv]['depends']
+        depends = packages[p].version_hints[bv]['depends']
         depends = package.deplist_without_versions(depends)
 
         for d in depends:
@@ -530,7 +514,7 @@ def python_rebuild(args, packages, fn, reportlist):
             pr.pn = p
             pr.po = po
             pr.spn = po.srcpackage(bv)
-            pr.spo = packages[arch][pr.spn]
+            pr.spo = packages[pr.spn]
             pr.depends = d
             pr.bv = bv
 
@@ -550,9 +534,9 @@ def python_rebuild(args, packages, fn, reportlist):
         # that it needs updating
         pr = types.SimpleNamespace()
         pr.pn = 'python' + str(highest_ver) + '-' + m
-        pr.po = packages[arch][pr.pn]
+        pr.po = packages[pr.pn]
         pr.spn = pr.po.srcpackage(pr.po.best_version)
-        pr.spo = packages[arch][pr.spn]
+        pr.spo = packages[pr.spn]
         pr.depends = 'python' + str(highest_ver)
         pr.bv = pr.po.best_version
 
diff --git a/calm/untest.py b/calm/untest.py
index 49c4e5f..6ffd22f 100644
--- a/calm/untest.py
+++ b/calm/untest.py
@@ -42,7 +42,7 @@ def untest(pvr):
     # remove '^test:' lines from any package and subpackage hints
     removed = 0
     total = 0
-    for arch in common_constants.ARCHES + ['noarch']:
+    for arch in common_constants.ARCHES + ['noarch', 'src']:
         for (dirpath, _subdirs, files) in os.walk(os.path.join(common_constants.FTP, arch, 'release', p)):
             for f in files:
                 if re.match(r'.*-' + re.escape(vr) + r'.*\.hint$', f):
diff --git a/calm/uploads.py b/calm/uploads.py
index a58ac80..1c2d922 100644
--- a/calm/uploads.py
+++ b/calm/uploads.py
@@ -60,9 +60,8 @@ class ScanResult:
 #
 #
 
-def scan(scandir, m, all_packages, arch, args):
+def scan(scandir, m, all_packages, args):
     homedir = os.path.join(scandir, m.name)
-    basedir = os.path.join(homedir, arch)
 
     packages = {}
     move = MoveList(homedir)
@@ -73,22 +72,14 @@ def scan(scandir, m, all_packages, arch, args):
     mtimes = [('', 0)]
     ignored = 0
 
-    logging.debug('reading packages from %s' % (basedir))
-
-    # note mtime of any !ready file at top-level
-    for ready in [os.path.join(basedir, '!ready'), os.path.join(basedir, 'release', '!ready')]:
-        if os.path.exists(ready):
-            mtime = os.path.getmtime(ready)
-            mtimes.append(('', mtime))
-            logging.debug('processing files with mtime older than %d' % (mtime))
-            remove.append(ready)
+    logging.debug('reading packages from %s' % (homedir))
 
     # we record a timestamp when 'ignoring as there is no !ready' warnings were
     # last emitted
     logging.debug("reminder-timestamp %d, interval %d, next reminder %d, current time %d" % (m.reminder_time, REMINDER_INTERVAL, m.reminder_time + REMINDER_INTERVAL, time.time()))
 
     # scan package directories
-    for (dirpath, _subdirs, files) in os.walk(os.path.join(basedir, 'release')):
+    for (dirpath, _subdirs, files) in os.walk(homedir):
         relpath = os.path.relpath(dirpath, homedir)
         removed_files = []
 
@@ -97,12 +88,6 @@ def scan(scandir, m, all_packages, arch, args):
             if f.endswith('.bak'):
                 files.remove(f)
 
-        # skip uninteresting directories
-        if (not files) or (relpath == os.path.join(arch, 'release')):
-            continue
-
-        logging.debug('reading uploads from %s' % dirpath)
-
         # note the mtime of the !ready file
         if '!ready' in files:
             ready = os.path.join(dirpath, '!ready')
@@ -123,7 +108,26 @@ def scan(scandir, m, all_packages, arch, args):
                 else:
                     mtimes.pop()
 
-        # only process files newer than !ready
+        # verify leading component of the path is a valid arch
+        splitpath = relpath.split(os.path.sep)
+        arch = splitpath[0]
+        if arch not in common_constants.ARCHES + ['noarch', 'src', '.'] + common_constants.ARCHIVED_ARCHES:
+            logging.warning("Ignoring unexpected arch directory '%s' " % (arch))
+            continue
+
+        # filter out expected maintainer-root detritus
+        if len(splitpath) <= 1:
+            for f in sorted(files):
+                if f in ['.last-seen', '.sftp-session-close', '!reminder-timestamp', '!scallywag', '!mail', '!email']:
+                    files.remove(f)
+
+        # skip uninteresting directories
+        if not files:
+            continue
+
+        logging.debug('reading uploads from %s' % dirpath)
+
+        # only process files older than !ready
         for f in sorted(files):
             fn = os.path.join(dirpath, f)
             file_mtime = os.path.getmtime(fn)
@@ -149,9 +153,8 @@ def scan(scandir, m, all_packages, arch, args):
         # (removal is only controlled by these checks, uploads are more complex,
         # with the full auth check in auth_check() below)
 
-        # package doesn't appear in package list at all
-        (_, _, pkgpath) = relpath.split(os.sep, 2)
-        superpackage = pkgpath.split(os.sep, 1)[0]
+        # package doesn't appear in package list at all?
+        superpackage = splitpath[2]
         if superpackage not in all_packages:
             logging.error("package '%s' is not in the package list" % superpackage)
             continue
@@ -219,11 +222,6 @@ def scan(scandir, m, all_packages, arch, args):
             rel_fn = os.path.join(relpath, f)
             logging.debug("processing %s" % rel_fn)
 
-            # ignore !mail and !email (which we have already read)
-            if f in ['!mail', '!email']:
-                files.remove(f)
-                continue
-
             # ignore in-progress sftp uploads. Net::SFTP::SftpServer uses
             # temporary upload filenames ending with '.SftpXFR.<pid>'
             if re.search(r'\.SftpXFR\.\d*$', f):
@@ -274,7 +272,7 @@ def scan(scandir, m, all_packages, arch, args):
                 continue
 
             # does file already exist in release area?
-            # XXX: this needs to be done later to be multipath aware
+            # XXX: this needs to be redone later to be multipath aware
             dest = os.path.join(args.rel_area, relpath, f)
             if os.path.isfile(dest):
                 if not f.endswith('.hint'):
@@ -321,7 +319,7 @@ def scan(scandir, m, all_packages, arch, args):
     # since we warned about files being ignored, warn again
     if ignored > 0:
         if (time.time() > (m.reminder_time + REMINDER_INTERVAL)):
-            logging.warning("ignored %d files in %s as there is no !ready" % (ignored, arch))
+            logging.warning("ignored %d files as there is no !ready" % (ignored))
             if not args.dryrun:
                 m.reminders_issued = True
 
@@ -364,11 +362,10 @@ def auth_check(args, m, scan_result, packages):
     # package. (i.e. you can upload a new version of a package in a different
     # place, if you are allowed to upload in the old place as well)
     for p in scan_result.packages:
-        for arch in packages:
-            if p in packages[arch]:
-                for ap in packages[arch][p].auth_path:
-                    if ap not in m.pkgs:
-                        logging.error("package '%s' needs authorization '%s' not in the package list for maintainer '%s'" % (p, ap, m.name))
-                        scan_result.error = True
-                    else:
-                        logging.debug("package '%s' has authorization '%s' in the package list for maintainer '%s'" % (p, ap, m.name))
+        if p in packages:
+            for ap in packages[p].auth_path:
+                if ap not in m.pkgs:
+                    logging.error("package '%s' needs authorization '%s' not in the package list for maintainer '%s'" % (p, ap, m.name))
+                    scan_result.error = True
+                else:
+                    logging.debug("package '%s' has authorization '%s' in the package list for maintainer '%s'" % (p, ap, m.name))
diff --git a/test/test_calm.py b/test/test_calm.py
index a3e06c6..c87ad6c 100755
--- a/test/test_calm.py
+++ b/test/test_calm.py
@@ -40,7 +40,6 @@ import types
 import unittest
 
 import calm.calm
-import calm.common_constants as common_constants
 import calm.hint as hint
 import calm.maintainers as maintainers
 import calm.package as package
@@ -142,7 +141,6 @@ class CalmTest(unittest.TestCase):
 
         htdocs = 'testdata/htdocs'
         args = types.SimpleNamespace()
-        args.arch = 'x86_64'
         args.htdocs = htdocs
         args.rel_area = 'testdata/relarea'
         args.homedir = 'testdata/homes'
@@ -156,11 +154,8 @@ class CalmTest(unittest.TestCase):
         except FileNotFoundError:
             pass
 
-        packages = {}
-        for arch in common_constants.ARCHES:
-            packages[arch] = {}
-        packages[args.arch], _ = package.read_packages(args.rel_area, args.arch)
-        package.validate_packages(args, packages[args.arch])
+        packages, _ = package.read_packages(args.rel_area)
+        package.validate_packages(args, packages)
         pkg2html.update_package_listings(args, packages)
 
         # compare the output dirtree with expected
@@ -334,7 +329,7 @@ class CalmTest(unittest.TestCase):
         for (f, t) in ready_fns:
             os.system('touch %s "%s"' % (t, f))
 
-        scan_result = uploads.scan('testdata/homes', m, pkglist + ['not-on-maintainer-list'], args.arch, args)
+        scan_result = uploads.scan('testdata/homes', m, pkglist + ['not-on-maintainer-list'], args)
 
         os.chdir(oldcwd)
         shutil.rmtree(test_root)
@@ -360,7 +355,7 @@ class CalmTest(unittest.TestCase):
         args.release = 'testing'
         args.setup_version = '4.321'
 
-        packages, _ = package.read_packages(args.rel_area, args.arch)
+        packages, _ = package.read_packages(args.rel_area)
         package.delete(packages, 'x86_64/release/nonexistent', 'nosuchfile-1.0.0.tar.xz')
         self.assertEqual(package.validate_packages(args, packages), True)
         package.write_setup_ini(args, packages, args.arch)
@@ -486,7 +481,7 @@ class CalmTest(unittest.TestCase):
         self.assertTrue(packages)
 
         pkg2html.update_package_listings(args, packages)
-        package.write_setup_ini(args, packages['x86_64'], 'x86_64')
+        package.write_setup_ini(args, packages, 'x86_64')
         reports.do_reports(args, packages)
 
         with open(os.path.join(args.rel_area, 'setup.ini')) as inifile:
diff --git a/test/testdata/htdocs.expected/dirtree.expected b/test/testdata/htdocs.expected/dirtree.expected
index 15cfa5f..8b8343a 100644
--- a/test/testdata/htdocs.expected/dirtree.expected
+++ b/test/testdata/htdocs.expected/dirtree.expected
@@ -1,6 +1,43 @@
 {'.': ['packages.inc', 'packages_docs.inc', 'src_packages.inc'],
  'doc': ['.htaccess'],
  'doc/keychain': ['keychain.README'],
+ 'noarch': ['.htaccess'],
+ 'noarch/obs-a': ['.htaccess', 'obs-a-1.0-1'],
+ 'noarch/obs-b': ['.htaccess', 'obs-b-1.0-1'],
+ 'noarch/perl-Net-SMTP-SSL': ['.htaccess',
+                              'perl-Net-SMTP-SSL-1.01-1',
+                              'perl-Net-SMTP-SSL-1.02-1',
+                              'perl-Net-SMTP-SSL-1.03-1'],
+ 'noarch/test-c': ['.htaccess', 'test-c-1.0-1'],
+ 'noarch/test-d': ['.htaccess', 'test-d-1.0.42590-1'],
+ 'noarch/test-e': ['.htaccess', 'test-e-1.0-1'],
+ 'src': ['.htaccess'],
+ 'src/arc-src': ['.htaccess', 'arc-4.32.7-10-src'],
+ 'src/corrupt-src': ['.htaccess', 'corrupt-2.0.0-1-src'],
+ 'src/cygwin-src': ['.htaccess', 'cygwin-2.2.0-1-src', 'cygwin-2.2.1-1-src', 'cygwin-2.3.0-0.3-src'],
+ 'src/keychain-src': ['.htaccess', 'keychain-2.6.8-1-src', 'keychain-2.7.1-1-src'],
+ 'src/mDNSResponder-src': ['.htaccess', 'mDNSResponder-379.32.1-1-src'],
+ 'src/obs-a-src': ['.htaccess', 'obs-a-1.0-1-src'],
+ 'src/obs-b-src': ['.htaccess', 'obs-b-1.0-1-src'],
+ 'src/openssh-src': ['.htaccess', 'openssh-7.2p2-1-src'],
+ 'src/per-version-replacement-hint-only-src': ['.htaccess', 'per-version-replacement-hint-only-1.0-1-src'],
+ 'src/per-version-src': ['.htaccess', 'per-version-4.0-1-src', 'per-version-4.8-1-src'],
+ 'src/perl-Net-SMTP-SSL-src': ['.htaccess',
+                               'perl-Net-SMTP-SSL-1.01-1-src',
+                               'perl-Net-SMTP-SSL-1.02-1-src',
+                               'perl-Net-SMTP-SSL-1.03-1-src'],
+ 'src/rpm-doc-src': ['.htaccess', 'rpm-doc-4.1-2-src'],
+ 'src/staleversion-src': ['.htaccess',
+                          'staleversion-240-1-src',
+                          'staleversion-242-0-src',
+                          'staleversion-243-0-src',
+                          'staleversion-250-0-src',
+                          'staleversion-251-0-src',
+                          'staleversion-260-0-src'],
+ 'src/test-c-src': ['.htaccess', 'test-c-1.0-1-src'],
+ 'src/test-d-src': ['.htaccess', 'test-d-1.0.42590-1-src'],
+ 'src/test-e-src': ['.htaccess', 'test-e-1.0-1-src'],
+ 'src/testpackage-src': ['.htaccess', 'testpackage-0.1-1-src'],
  'summary': ['arc-src.html',
              'arc.html',
              'base-cygwin.html',
@@ -42,43 +79,22 @@
              'testpackage.html'],
  'x86_64': ['.htaccess'],
  'x86_64/arc': ['.htaccess', 'arc-4.32.7-10'],
- 'x86_64/arc-src': ['.htaccess', 'arc-4.32.7-10-src'],
  'x86_64/base-cygwin': ['.htaccess', 'base-cygwin-3.6-1', 'base-cygwin-3.8-1'],
  'x86_64/corrupt': ['.htaccess', 'corrupt-2.0.0-1'],
- 'x86_64/corrupt-src': ['.htaccess', 'corrupt-2.0.0-1-src'],
  'x86_64/cygwin': ['.htaccess', 'cygwin-2.2.0-1', 'cygwin-2.2.1-1', 'cygwin-2.3.0-0.3'],
  'x86_64/cygwin-debuginfo': ['.htaccess',
                              'cygwin-debuginfo-2.2.0-1',
                              'cygwin-debuginfo-2.2.1-1',
                              'cygwin-debuginfo-2.3.0-0.3'],
  'x86_64/cygwin-devel': ['.htaccess', 'cygwin-devel-2.2.0-1', 'cygwin-devel-2.2.1-1', 'cygwin-devel-2.3.0-0.3'],
- 'x86_64/cygwin-src': ['.htaccess', 'cygwin-2.2.0-1-src', 'cygwin-2.2.1-1-src', 'cygwin-2.3.0-0.3-src'],
  'x86_64/keychain': ['.htaccess', 'keychain-2.6.8-1', 'keychain-2.7.1-1'],
- 'x86_64/keychain-src': ['.htaccess', 'keychain-2.6.8-1-src', 'keychain-2.7.1-1-src'],
  'x86_64/libdns_sd-devel': ['.htaccess', 'libdns_sd-devel-379.32.1-1'],
  'x86_64/libdns_sd1': ['.htaccess', 'libdns_sd1-379.32.1-1'],
  'x86_64/mDNSResponder': ['.htaccess', 'mDNSResponder-379.32.1-1'],
- 'x86_64/mDNSResponder-src': ['.htaccess', 'mDNSResponder-379.32.1-1-src'],
- 'x86_64/obs-a': ['.htaccess', 'obs-a-1.0-1'],
- 'x86_64/obs-a-src': ['.htaccess', 'obs-a-1.0-1-src'],
- 'x86_64/obs-b': ['.htaccess', 'obs-b-1.0-1'],
- 'x86_64/obs-b-src': ['.htaccess', 'obs-b-1.0-1-src'],
  'x86_64/openssh': ['.htaccess', 'openssh-7.2p2-1'],
- 'x86_64/openssh-src': ['.htaccess', 'openssh-7.2p2-1-src'],
  'x86_64/per-version': ['.htaccess', 'per-version-4.0-1', 'per-version-4.8-1'],
  'x86_64/per-version-replacement-hint-only': ['.htaccess', 'per-version-replacement-hint-only-1.0-1'],
- 'x86_64/per-version-replacement-hint-only-src': ['.htaccess', 'per-version-replacement-hint-only-1.0-1-src'],
- 'x86_64/per-version-src': ['.htaccess', 'per-version-4.0-1-src', 'per-version-4.8-1-src'],
- 'x86_64/perl-Net-SMTP-SSL': ['.htaccess',
-                              'perl-Net-SMTP-SSL-1.01-1',
-                              'perl-Net-SMTP-SSL-1.02-1',
-                              'perl-Net-SMTP-SSL-1.03-1'],
- 'x86_64/perl-Net-SMTP-SSL-src': ['.htaccess',
-                                  'perl-Net-SMTP-SSL-1.01-1-src',
-                                  'perl-Net-SMTP-SSL-1.02-1-src',
-                                  'perl-Net-SMTP-SSL-1.03-1-src'],
  'x86_64/rpm-doc': ['.htaccess', 'rpm-doc-4.1-2', 'rpm-doc-999-1'],
- 'x86_64/rpm-doc-src': ['.htaccess', 'rpm-doc-4.1-2-src'],
  'x86_64/staleversion': ['.htaccess',
                          'staleversion-240-1',
                          'staleversion-242-0',
@@ -86,18 +102,4 @@
                          'staleversion-250-0',
                          'staleversion-251-0',
                          'staleversion-260-0'],
- 'x86_64/staleversion-src': ['.htaccess',
-                             'staleversion-240-1-src',
-                             'staleversion-242-0-src',
-                             'staleversion-243-0-src',
-                             'staleversion-250-0-src',
-                             'staleversion-251-0-src',
-                             'staleversion-260-0-src'],
- 'x86_64/test-c': ['.htaccess', 'test-c-1.0-1'],
- 'x86_64/test-c-src': ['.htaccess', 'test-c-1.0-1-src'],
- 'x86_64/test-d': ['.htaccess', 'test-d-1.0.42590-1'],
- 'x86_64/test-d-src': ['.htaccess', 'test-d-1.0.42590-1-src'],
- 'x86_64/test-e': ['.htaccess', 'test-e-1.0-1'],
- 'x86_64/test-e-src': ['.htaccess', 'test-e-1.0-1-src'],
- 'x86_64/testpackage': ['.htaccess', 'testpackage-0.1-1'],
- 'x86_64/testpackage-src': ['.htaccess', 'testpackage-0.1-1-src']}
+ 'x86_64/testpackage': ['.htaccess', 'testpackage-0.1-1']}
diff --git a/test/testdata/htdocs.expected/noarch/.htaccess b/test/testdata/htdocs.expected/noarch/.htaccess
new file mode 100644
index 0000000..325fa67
--- /dev/null
+++ b/test/testdata/htdocs.expected/noarch/.htaccess
@@ -0,0 +1 @@
+Redirect temp /packages/noarch/index.html https://cygwin.com/packages/package_list.html
diff --git a/test/testdata/htdocs.expected/noarch/obs-a/.htaccess b/test/testdata/htdocs.expected/noarch/obs-a/.htaccess
new file mode 100644
index 0000000..33fc60d
--- /dev/null
+++ b/test/testdata/htdocs.expected/noarch/obs-a/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/obs-a/$ /packages/summary/obs-a.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-a/obs-a-1.0-1 b/test/testdata/htdocs.expected/noarch/obs-a/obs-a-1.0-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/obs-a/obs-a-1.0-1
rename to test/testdata/htdocs.expected/noarch/obs-a/obs-a-1.0-1
diff --git a/test/testdata/htdocs.expected/noarch/obs-b/.htaccess b/test/testdata/htdocs.expected/noarch/obs-b/.htaccess
new file mode 100644
index 0000000..6a21b65
--- /dev/null
+++ b/test/testdata/htdocs.expected/noarch/obs-b/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/obs-b/$ /packages/summary/obs-b.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-b/obs-b-1.0-1 b/test/testdata/htdocs.expected/noarch/obs-b/obs-b-1.0-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/obs-b/obs-b-1.0-1
rename to test/testdata/htdocs.expected/noarch/obs-b/obs-b-1.0-1
diff --git a/test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/.htaccess b/test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/.htaccess
new file mode 100644
index 0000000..f0f554b
--- /dev/null
+++ b/test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/perl-Net-SMTP-SSL/$ /packages/summary/perl-Net-SMTP-SSL.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1 b/test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1
rename to test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1 b/test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1
rename to test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1 b/test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1
rename to test/testdata/htdocs.expected/noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1
diff --git a/test/testdata/htdocs.expected/noarch/test-c/.htaccess b/test/testdata/htdocs.expected/noarch/test-c/.htaccess
new file mode 100644
index 0000000..20c2320
--- /dev/null
+++ b/test/testdata/htdocs.expected/noarch/test-c/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/test-c/$ /packages/summary/test-c.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-c/test-c-1.0-1 b/test/testdata/htdocs.expected/noarch/test-c/test-c-1.0-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/test-c/test-c-1.0-1
rename to test/testdata/htdocs.expected/noarch/test-c/test-c-1.0-1
diff --git a/test/testdata/htdocs.expected/noarch/test-d/.htaccess b/test/testdata/htdocs.expected/noarch/test-d/.htaccess
new file mode 100644
index 0000000..09cee96
--- /dev/null
+++ b/test/testdata/htdocs.expected/noarch/test-d/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/test-d/$ /packages/summary/test-d.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-d/test-d-1.0.42590-1 b/test/testdata/htdocs.expected/noarch/test-d/test-d-1.0.42590-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/test-d/test-d-1.0.42590-1
rename to test/testdata/htdocs.expected/noarch/test-d/test-d-1.0.42590-1
diff --git a/test/testdata/htdocs.expected/noarch/test-e/.htaccess b/test/testdata/htdocs.expected/noarch/test-e/.htaccess
new file mode 100644
index 0000000..4881633
--- /dev/null
+++ b/test/testdata/htdocs.expected/noarch/test-e/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/test-e/$ /packages/summary/test-e.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-e/test-e-1.0-1 b/test/testdata/htdocs.expected/noarch/test-e/test-e-1.0-1
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/test-e/test-e-1.0-1
rename to test/testdata/htdocs.expected/noarch/test-e/test-e-1.0-1
diff --git a/test/testdata/htdocs.expected/src/.htaccess b/test/testdata/htdocs.expected/src/.htaccess
new file mode 100644
index 0000000..8227f7e
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/.htaccess
@@ -0,0 +1 @@
+Redirect temp /packages/src/index.html https://cygwin.com/packages/package_list.html
diff --git a/test/testdata/htdocs.expected/src/arc-src/.htaccess b/test/testdata/htdocs.expected/src/arc-src/.htaccess
new file mode 100644
index 0000000..a69e8f9
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/arc-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/arc-src/$ /packages/summary/arc-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/arc-src/arc-4.32.7-10-src b/test/testdata/htdocs.expected/src/arc-src/arc-4.32.7-10-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/arc-src/arc-4.32.7-10-src
rename to test/testdata/htdocs.expected/src/arc-src/arc-4.32.7-10-src
diff --git a/test/testdata/htdocs.expected/src/corrupt-src/.htaccess b/test/testdata/htdocs.expected/src/corrupt-src/.htaccess
new file mode 100644
index 0000000..b8211d5
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/corrupt-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/corrupt-src/$ /packages/summary/corrupt-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/corrupt-src/corrupt-2.0.0-1-src b/test/testdata/htdocs.expected/src/corrupt-src/corrupt-2.0.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/corrupt-src/corrupt-2.0.0-1-src
rename to test/testdata/htdocs.expected/src/corrupt-src/corrupt-2.0.0-1-src
diff --git a/test/testdata/htdocs.expected/src/cygwin-src/.htaccess b/test/testdata/htdocs.expected/src/cygwin-src/.htaccess
new file mode 100644
index 0000000..cbacc7c
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/cygwin-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/cygwin-src/$ /packages/summary/cygwin-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin-src/cygwin-2.2.0-1-src b/test/testdata/htdocs.expected/src/cygwin-src/cygwin-2.2.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/cygwin-src/cygwin-2.2.0-1-src
rename to test/testdata/htdocs.expected/src/cygwin-src/cygwin-2.2.0-1-src
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin-src/cygwin-2.2.1-1-src b/test/testdata/htdocs.expected/src/cygwin-src/cygwin-2.2.1-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/cygwin-src/cygwin-2.2.1-1-src
rename to test/testdata/htdocs.expected/src/cygwin-src/cygwin-2.2.1-1-src
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin-src/cygwin-2.3.0-0.3-src b/test/testdata/htdocs.expected/src/cygwin-src/cygwin-2.3.0-0.3-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/cygwin-src/cygwin-2.3.0-0.3-src
rename to test/testdata/htdocs.expected/src/cygwin-src/cygwin-2.3.0-0.3-src
diff --git a/test/testdata/htdocs.expected/src/keychain-src/.htaccess b/test/testdata/htdocs.expected/src/keychain-src/.htaccess
new file mode 100644
index 0000000..2a26079
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/keychain-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/keychain-src/$ /packages/summary/keychain-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/keychain-src/keychain-2.6.8-1-src b/test/testdata/htdocs.expected/src/keychain-src/keychain-2.6.8-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/keychain-src/keychain-2.6.8-1-src
rename to test/testdata/htdocs.expected/src/keychain-src/keychain-2.6.8-1-src
diff --git a/test/testdata/htdocs.expected/x86_64/keychain-src/keychain-2.7.1-1-src b/test/testdata/htdocs.expected/src/keychain-src/keychain-2.7.1-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/keychain-src/keychain-2.7.1-1-src
rename to test/testdata/htdocs.expected/src/keychain-src/keychain-2.7.1-1-src
diff --git a/test/testdata/htdocs.expected/src/mDNSResponder-src/.htaccess b/test/testdata/htdocs.expected/src/mDNSResponder-src/.htaccess
new file mode 100644
index 0000000..d64b0ed
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/mDNSResponder-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/mDNSResponder-src/$ /packages/summary/mDNSResponder-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/mDNSResponder-src/mDNSResponder-379.32.1-1-src b/test/testdata/htdocs.expected/src/mDNSResponder-src/mDNSResponder-379.32.1-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/mDNSResponder-src/mDNSResponder-379.32.1-1-src
rename to test/testdata/htdocs.expected/src/mDNSResponder-src/mDNSResponder-379.32.1-1-src
diff --git a/test/testdata/htdocs.expected/src/obs-a-src/.htaccess b/test/testdata/htdocs.expected/src/obs-a-src/.htaccess
new file mode 100644
index 0000000..89e1702
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/obs-a-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/obs-a-src/$ /packages/summary/obs-a-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-a-src/obs-a-1.0-1-src b/test/testdata/htdocs.expected/src/obs-a-src/obs-a-1.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/obs-a-src/obs-a-1.0-1-src
rename to test/testdata/htdocs.expected/src/obs-a-src/obs-a-1.0-1-src
diff --git a/test/testdata/htdocs.expected/src/obs-b-src/.htaccess b/test/testdata/htdocs.expected/src/obs-b-src/.htaccess
new file mode 100644
index 0000000..f588014
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/obs-b-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/obs-b-src/$ /packages/summary/obs-b-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-b-src/obs-b-1.0-1-src b/test/testdata/htdocs.expected/src/obs-b-src/obs-b-1.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/obs-b-src/obs-b-1.0-1-src
rename to test/testdata/htdocs.expected/src/obs-b-src/obs-b-1.0-1-src
diff --git a/test/testdata/htdocs.expected/src/openssh-src/.htaccess b/test/testdata/htdocs.expected/src/openssh-src/.htaccess
new file mode 100644
index 0000000..94b8205
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/openssh-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/openssh-src/$ /packages/summary/openssh-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/openssh-src/openssh-7.2p2-1-src b/test/testdata/htdocs.expected/src/openssh-src/openssh-7.2p2-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/openssh-src/openssh-7.2p2-1-src
rename to test/testdata/htdocs.expected/src/openssh-src/openssh-7.2p2-1-src
diff --git a/test/testdata/htdocs.expected/src/per-version-replacement-hint-only-src/.htaccess b/test/testdata/htdocs.expected/src/per-version-replacement-hint-only-src/.htaccess
new file mode 100644
index 0000000..c25408b
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/per-version-replacement-hint-only-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/per-version-replacement-hint-only-src/$ /packages/summary/per-version-replacement-hint-only-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only-src/per-version-replacement-hint-only-1.0-1-src b/test/testdata/htdocs.expected/src/per-version-replacement-hint-only-src/per-version-replacement-hint-only-1.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only-src/per-version-replacement-hint-only-1.0-1-src
rename to test/testdata/htdocs.expected/src/per-version-replacement-hint-only-src/per-version-replacement-hint-only-1.0-1-src
diff --git a/test/testdata/htdocs.expected/src/per-version-src/.htaccess b/test/testdata/htdocs.expected/src/per-version-src/.htaccess
new file mode 100644
index 0000000..d767b0e
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/per-version-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/per-version-src/$ /packages/summary/per-version-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/per-version-src/per-version-4.0-1-src b/test/testdata/htdocs.expected/src/per-version-src/per-version-4.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/per-version-src/per-version-4.0-1-src
rename to test/testdata/htdocs.expected/src/per-version-src/per-version-4.0-1-src
diff --git a/test/testdata/htdocs.expected/x86_64/per-version-src/per-version-4.8-1-src b/test/testdata/htdocs.expected/src/per-version-src/per-version-4.8-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/per-version-src/per-version-4.8-1-src
rename to test/testdata/htdocs.expected/src/per-version-src/per-version-4.8-1-src
diff --git a/test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/.htaccess b/test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/.htaccess
new file mode 100644
index 0000000..504fc1f
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/perl-Net-SMTP-SSL-src/$ /packages/summary/perl-Net-SMTP-SSL-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.01-1-src b/test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.01-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.01-1-src
rename to test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.01-1-src
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.02-1-src b/test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.02-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.02-1-src
rename to test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.02-1-src
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.03-1-src b/test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.03-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.03-1-src
rename to test/testdata/htdocs.expected/src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.03-1-src
diff --git a/test/testdata/htdocs.expected/src/rpm-doc-src/.htaccess b/test/testdata/htdocs.expected/src/rpm-doc-src/.htaccess
new file mode 100644
index 0000000..02b3dbb
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/rpm-doc-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/rpm-doc-src/$ /packages/summary/rpm-doc-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/rpm-doc-src/rpm-doc-4.1-2-src b/test/testdata/htdocs.expected/src/rpm-doc-src/rpm-doc-4.1-2-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/rpm-doc-src/rpm-doc-4.1-2-src
rename to test/testdata/htdocs.expected/src/rpm-doc-src/rpm-doc-4.1-2-src
diff --git a/test/testdata/htdocs.expected/src/staleversion-src/.htaccess b/test/testdata/htdocs.expected/src/staleversion-src/.htaccess
new file mode 100644
index 0000000..4969c6a
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/staleversion-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/staleversion-src/$ /packages/summary/staleversion-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-240-1-src b/test/testdata/htdocs.expected/src/staleversion-src/staleversion-240-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-240-1-src
rename to test/testdata/htdocs.expected/src/staleversion-src/staleversion-240-1-src
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-242-0-src b/test/testdata/htdocs.expected/src/staleversion-src/staleversion-242-0-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-242-0-src
rename to test/testdata/htdocs.expected/src/staleversion-src/staleversion-242-0-src
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-243-0-src b/test/testdata/htdocs.expected/src/staleversion-src/staleversion-243-0-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-243-0-src
rename to test/testdata/htdocs.expected/src/staleversion-src/staleversion-243-0-src
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-250-0-src b/test/testdata/htdocs.expected/src/staleversion-src/staleversion-250-0-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-250-0-src
rename to test/testdata/htdocs.expected/src/staleversion-src/staleversion-250-0-src
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-251-0-src b/test/testdata/htdocs.expected/src/staleversion-src/staleversion-251-0-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-251-0-src
rename to test/testdata/htdocs.expected/src/staleversion-src/staleversion-251-0-src
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-260-0-src b/test/testdata/htdocs.expected/src/staleversion-src/staleversion-260-0-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/staleversion-src/staleversion-260-0-src
rename to test/testdata/htdocs.expected/src/staleversion-src/staleversion-260-0-src
diff --git a/test/testdata/htdocs.expected/src/test-c-src/.htaccess b/test/testdata/htdocs.expected/src/test-c-src/.htaccess
new file mode 100644
index 0000000..78b011c
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/test-c-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/test-c-src/$ /packages/summary/test-c-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-c-src/test-c-1.0-1-src b/test/testdata/htdocs.expected/src/test-c-src/test-c-1.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/test-c-src/test-c-1.0-1-src
rename to test/testdata/htdocs.expected/src/test-c-src/test-c-1.0-1-src
diff --git a/test/testdata/htdocs.expected/src/test-d-src/.htaccess b/test/testdata/htdocs.expected/src/test-d-src/.htaccess
new file mode 100644
index 0000000..5b31609
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/test-d-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/test-d-src/$ /packages/summary/test-d-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-d-src/test-d-1.0.42590-1-src b/test/testdata/htdocs.expected/src/test-d-src/test-d-1.0.42590-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/test-d-src/test-d-1.0.42590-1-src
rename to test/testdata/htdocs.expected/src/test-d-src/test-d-1.0.42590-1-src
diff --git a/test/testdata/htdocs.expected/src/test-e-src/.htaccess b/test/testdata/htdocs.expected/src/test-e-src/.htaccess
new file mode 100644
index 0000000..f138191
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/test-e-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/test-e-src/$ /packages/summary/test-e-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-e-src/test-e-1.0-1-src b/test/testdata/htdocs.expected/src/test-e-src/test-e-1.0-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/test-e-src/test-e-1.0-1-src
rename to test/testdata/htdocs.expected/src/test-e-src/test-e-1.0-1-src
diff --git a/test/testdata/htdocs.expected/src/testpackage-src/.htaccess b/test/testdata/htdocs.expected/src/testpackage-src/.htaccess
new file mode 100644
index 0000000..82cf26b
--- /dev/null
+++ b/test/testdata/htdocs.expected/src/testpackage-src/.htaccess
@@ -0,0 +1,2 @@
+RedirectMatch temp /packages/src/testpackage-src/$ /packages/summary/testpackage-src.html
+ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/testpackage-src/testpackage-0.1-1-src b/test/testdata/htdocs.expected/src/testpackage-src/testpackage-0.1-1-src
similarity index 100%
rename from test/testdata/htdocs.expected/x86_64/testpackage-src/testpackage-0.1-1-src
rename to test/testdata/htdocs.expected/src/testpackage-src/testpackage-0.1-1-src
diff --git a/test/testdata/htdocs.expected/summary/arc-src.html b/test/testdata/htdocs.expected/summary/arc-src.html
index d10edaa..c2794d0 100755
--- a/test/testdata/htdocs.expected/summary/arc-src.html
+++ b/test/testdata/htdocs.expected/summary/arc-src.html
@@ -26,7 +26,7 @@ the best of packing, squeezing, or crunching is used.</p></td></tr>
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>4.32.7-10</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/arc-src/arc-4.32.7-10-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>4.32.7-10</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/arc-src/arc-4.32.7-10-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/arc.html b/test/testdata/htdocs.expected/summary/arc.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/base-cygwin.html b/test/testdata/htdocs.expected/summary/base-cygwin.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/corrupt-src.html b/test/testdata/htdocs.expected/summary/corrupt-src.html
index 9a182d0..3cee76d 100755
--- a/test/testdata/htdocs.expected/summary/corrupt-src.html
+++ b/test/testdata/htdocs.expected/summary/corrupt-src.html
@@ -21,7 +21,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>2.0.0-1</td><td>src</td><td class="right">354 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/corrupt-src/corrupt-2.0.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>2.0.0-1</td><td>src</td><td class="right">354 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/corrupt-src/corrupt-2.0.0-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/corrupt.html b/test/testdata/htdocs.expected/summary/corrupt.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/cygwin-debuginfo.html b/test/testdata/htdocs.expected/summary/cygwin-debuginfo.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/cygwin-devel.html b/test/testdata/htdocs.expected/summary/cygwin-devel.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/cygwin-src.html b/test/testdata/htdocs.expected/summary/cygwin-src.html
index ca0eac2..5d24971 100755
--- a/test/testdata/htdocs.expected/summary/cygwin-src.html
+++ b/test/testdata/htdocs.expected/summary/cygwin-src.html
@@ -23,9 +23,9 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>2.2.0-1</td><td>src</td><td class="right">1 KiB</td><td>2016-11-01 00:00</td><td>[<a href="../x86_64/cygwin-src/cygwin-2.2.0-1-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>2.2.1-1</td><td>src</td><td class="right">1 KiB</td><td>2016-11-02 00:00</td><td>[<a href="../x86_64/cygwin-src/cygwin-2.2.1-1-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>2.3.0-0.3</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/cygwin-src/cygwin-2.3.0-0.3-src">list of files</a>]</td><td>test</td></tr>
+<tr><td>2.2.0-1</td><td>src</td><td class="right">1 KiB</td><td>2016-11-01 00:00</td><td>[<a href="../src/cygwin-src/cygwin-2.2.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>2.2.1-1</td><td>src</td><td class="right">1 KiB</td><td>2016-11-02 00:00</td><td>[<a href="../src/cygwin-src/cygwin-2.2.1-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>2.3.0-0.3</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/cygwin-src/cygwin-2.3.0-0.3-src">list of files</a>]</td><td>test</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/cygwin.html b/test/testdata/htdocs.expected/summary/cygwin.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/keychain-src.html b/test/testdata/htdocs.expected/summary/keychain-src.html
index 80467ee..b09df93 100755
--- a/test/testdata/htdocs.expected/summary/keychain-src.html
+++ b/test/testdata/htdocs.expected/summary/keychain-src.html
@@ -29,8 +29,8 @@ necessary</p></td></tr>
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>2.6.8-1</td><td>src</td><td class="right">36 KiB</td><td>2016-11-02 00:00</td><td>[<a href="../x86_64/keychain-src/keychain-2.6.8-1-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>2.7.1-1</td><td>src</td><td class="right">132 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/keychain-src/keychain-2.7.1-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>2.6.8-1</td><td>src</td><td class="right">36 KiB</td><td>2016-11-02 00:00</td><td>[<a href="../src/keychain-src/keychain-2.6.8-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>2.7.1-1</td><td>src</td><td class="right">132 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/keychain-src/keychain-2.7.1-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/keychain.html b/test/testdata/htdocs.expected/summary/keychain.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/libdns_sd-devel.html b/test/testdata/htdocs.expected/summary/libdns_sd-devel.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/libdns_sd1.html b/test/testdata/htdocs.expected/summary/libdns_sd1.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/mDNSResponder-src.html b/test/testdata/htdocs.expected/summary/mDNSResponder-src.html
index 59d3816..b4897b3 100755
--- a/test/testdata/htdocs.expected/summary/mDNSResponder-src.html
+++ b/test/testdata/htdocs.expected/summary/mDNSResponder-src.html
@@ -23,7 +23,7 @@ industry standard IP protocols.</p></td></tr>
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>379.32.1-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/mDNSResponder-src/mDNSResponder-379.32.1-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>379.32.1-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/mDNSResponder-src/mDNSResponder-379.32.1-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/mDNSResponder.html b/test/testdata/htdocs.expected/summary/mDNSResponder.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/obs-a-src.html b/test/testdata/htdocs.expected/summary/obs-a-src.html
index de4a680..aa382ad 100755
--- a/test/testdata/htdocs.expected/summary/obs-a-src.html
+++ b/test/testdata/htdocs.expected/summary/obs-a-src.html
@@ -21,7 +21,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/obs-a-src/obs-a-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/obs-a-src/obs-a-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/obs-a.html b/test/testdata/htdocs.expected/summary/obs-a.html
old mode 100644
new mode 100755
index 774c985..bce157a
--- a/test/testdata/htdocs.expected/summary/obs-a.html
+++ b/test/testdata/htdocs.expected/summary/obs-a.html
@@ -22,7 +22,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/obs-a/obs-a-1.0-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../noarch/obs-a/obs-a-1.0-1">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/obs-b-src.html b/test/testdata/htdocs.expected/summary/obs-b-src.html
index 9b2e61b..d50976c 100755
--- a/test/testdata/htdocs.expected/summary/obs-b-src.html
+++ b/test/testdata/htdocs.expected/summary/obs-b-src.html
@@ -21,7 +21,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/obs-b-src/obs-b-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/obs-b-src/obs-b-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/obs-b.html b/test/testdata/htdocs.expected/summary/obs-b.html
old mode 100644
new mode 100755
index 623cebd..37ff9a4
--- a/test/testdata/htdocs.expected/summary/obs-b.html
+++ b/test/testdata/htdocs.expected/summary/obs-b.html
@@ -22,7 +22,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/obs-b/obs-b-1.0-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../noarch/obs-b/obs-b-1.0-1">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/openssh-src.html b/test/testdata/htdocs.expected/summary/openssh-src.html
index c8dd26e..c3a25ec 100755
--- a/test/testdata/htdocs.expected/summary/openssh-src.html
+++ b/test/testdata/htdocs.expected/summary/openssh-src.html
@@ -23,7 +23,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>7.2p2-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/openssh-src/openssh-7.2p2-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>7.2p2-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/openssh-src/openssh-7.2p2-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/openssh.html b/test/testdata/htdocs.expected/summary/openssh.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/per-version-replacement-hint-only-src.html b/test/testdata/htdocs.expected/summary/per-version-replacement-hint-only-src.html
index da6c490..d7bed3a 100755
--- a/test/testdata/htdocs.expected/summary/per-version-replacement-hint-only-src.html
+++ b/test/testdata/htdocs.expected/summary/per-version-replacement-hint-only-src.html
@@ -21,7 +21,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/per-version-replacement-hint-only-src/per-version-replacement-hint-only-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/per-version-replacement-hint-only-src/per-version-replacement-hint-only-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/per-version-replacement-hint-only.html b/test/testdata/htdocs.expected/summary/per-version-replacement-hint-only.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/per-version-src.html b/test/testdata/htdocs.expected/summary/per-version-src.html
index 42cf350..e0a1dfa 100755
--- a/test/testdata/htdocs.expected/summary/per-version-src.html
+++ b/test/testdata/htdocs.expected/summary/per-version-src.html
@@ -21,8 +21,8 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>4.0-1</td><td>src</td><td class="right">1 KiB</td><td>2017-04-09 00:00</td><td>[<a href="../x86_64/per-version-src/per-version-4.0-1-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>4.8-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/per-version-src/per-version-4.8-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>4.0-1</td><td>src</td><td class="right">1 KiB</td><td>2017-04-09 00:00</td><td>[<a href="../src/per-version-src/per-version-4.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>4.8-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/per-version-src/per-version-4.8-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/per-version.html b/test/testdata/htdocs.expected/summary/per-version.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL-src.html b/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL-src.html
index efabb55..9dbb957 100755
--- a/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL-src.html
+++ b/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL-src.html
@@ -22,9 +22,9 @@ its network operations in order to support encrypted connections.</p></td></tr>
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.01-1</td><td>src</td><td class="right">3 KiB</td><td>2016-09-01 00:00</td><td>[<a href="../x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.01-1-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>1.02-1</td><td>src</td><td class="right">3 KiB</td><td>2016-10-01 00:00</td><td>[<a href="../x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.02-1-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>1.03-1</td><td>src</td><td class="right">3 KiB</td><td>2016-11-01 00:00</td><td>[<a href="../x86_64/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.03-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.01-1</td><td>src</td><td class="right">3 KiB</td><td>2016-09-01 00:00</td><td>[<a href="../src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.01-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.02-1</td><td>src</td><td class="right">3 KiB</td><td>2016-10-01 00:00</td><td>[<a href="../src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.02-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.03-1</td><td>src</td><td class="right">3 KiB</td><td>2016-11-01 00:00</td><td>[<a href="../src/perl-Net-SMTP-SSL-src/perl-Net-SMTP-SSL-1.03-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL.html b/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL.html
old mode 100644
new mode 100755
index 07c5b12..cada639
--- a/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL.html
+++ b/test/testdata/htdocs.expected/summary/perl-Net-SMTP-SSL.html
@@ -22,9 +22,9 @@ its network operations in order to support encrypted connections.</p></td></tr>
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.01-1</td><td>noarch</td><td class="right">4 KiB</td><td>2016-09-01 00:00</td><td>[<a href="../x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1">list of files</a>]</td><td>stable</td></tr>
-<tr><td>1.02-1</td><td>noarch</td><td class="right">4 KiB</td><td>2016-10-01 00:00</td><td>[<a href="../x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1">list of files</a>]</td><td>stable</td></tr>
-<tr><td>1.03-1</td><td>noarch</td><td class="right">4 KiB</td><td>2016-11-01 00:00</td><td>[<a href="../x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.01-1</td><td>noarch</td><td class="right">4 KiB</td><td>2016-09-01 00:00</td><td>[<a href="../noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.02-1</td><td>noarch</td><td class="right">4 KiB</td><td>2016-10-01 00:00</td><td>[<a href="../noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.03-1</td><td>noarch</td><td class="right">4 KiB</td><td>2016-11-01 00:00</td><td>[<a href="../noarch/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/rpm-doc-src.html b/test/testdata/htdocs.expected/summary/rpm-doc-src.html
index ae1ffa3..0a66ca4 100755
--- a/test/testdata/htdocs.expected/summary/rpm-doc-src.html
+++ b/test/testdata/htdocs.expected/summary/rpm-doc-src.html
@@ -18,7 +18,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>4.1-2</td><td>src</td><td class="right">1 KiB</td><td>2016-11-02 00:00</td><td>[<a href="../x86_64/rpm-doc-src/rpm-doc-4.1-2-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>4.1-2</td><td>src</td><td class="right">1 KiB</td><td>2016-11-02 00:00</td><td>[<a href="../src/rpm-doc-src/rpm-doc-4.1-2-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/rpm-doc.html b/test/testdata/htdocs.expected/summary/rpm-doc.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/staleversion-src.html b/test/testdata/htdocs.expected/summary/staleversion-src.html
index 91a289c..2bc7d7e 100755
--- a/test/testdata/htdocs.expected/summary/staleversion-src.html
+++ b/test/testdata/htdocs.expected/summary/staleversion-src.html
@@ -21,12 +21,12 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>240-1</td><td>src</td><td class="right">1 KiB</td><td>2017-04-07 00:00</td><td>[<a href="../x86_64/staleversion-src/staleversion-240-1-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>242-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-08 00:00</td><td>[<a href="../x86_64/staleversion-src/staleversion-242-0-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>243-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-09 00:00</td><td>[<a href="../x86_64/staleversion-src/staleversion-243-0-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>250-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-10 00:00</td><td>[<a href="../x86_64/staleversion-src/staleversion-250-0-src">list of files</a>]</td><td>stable</td></tr>
-<tr><td>251-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-09 00:00</td><td>[<a href="../x86_64/staleversion-src/staleversion-251-0-src">list of files</a>]</td><td>test</td></tr>
-<tr><td>260-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-12 00:00</td><td>[<a href="../x86_64/staleversion-src/staleversion-260-0-src">list of files</a>]</td><td>test</td></tr>
+<tr><td>240-1</td><td>src</td><td class="right">1 KiB</td><td>2017-04-07 00:00</td><td>[<a href="../src/staleversion-src/staleversion-240-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>242-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-08 00:00</td><td>[<a href="../src/staleversion-src/staleversion-242-0-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>243-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-09 00:00</td><td>[<a href="../src/staleversion-src/staleversion-243-0-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>250-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-10 00:00</td><td>[<a href="../src/staleversion-src/staleversion-250-0-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>251-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-09 00:00</td><td>[<a href="../src/staleversion-src/staleversion-251-0-src">list of files</a>]</td><td>test</td></tr>
+<tr><td>260-0</td><td>src</td><td class="right">1 KiB</td><td>2017-04-12 00:00</td><td>[<a href="../src/staleversion-src/staleversion-260-0-src">list of files</a>]</td><td>test</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/staleversion.html b/test/testdata/htdocs.expected/summary/staleversion.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/summary/test-c-src.html b/test/testdata/htdocs.expected/summary/test-c-src.html
index 098c371..33ad59c 100755
--- a/test/testdata/htdocs.expected/summary/test-c-src.html
+++ b/test/testdata/htdocs.expected/summary/test-c-src.html
@@ -21,7 +21,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/test-c-src/test-c-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/test-c-src/test-c-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/test-c.html b/test/testdata/htdocs.expected/summary/test-c.html
old mode 100644
new mode 100755
index 1b5ffd9..abffd34
--- a/test/testdata/htdocs.expected/summary/test-c.html
+++ b/test/testdata/htdocs.expected/summary/test-c.html
@@ -23,7 +23,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/test-c/test-c-1.0-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../noarch/test-c/test-c-1.0-1">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/test-d-src.html b/test/testdata/htdocs.expected/summary/test-d-src.html
index 66f361d..026e611 100755
--- a/test/testdata/htdocs.expected/summary/test-d-src.html
+++ b/test/testdata/htdocs.expected/summary/test-d-src.html
@@ -21,7 +21,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0.42590-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/test-d-src/test-d-1.0.42590-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0.42590-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/test-d-src/test-d-1.0.42590-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/test-d.html b/test/testdata/htdocs.expected/summary/test-d.html
old mode 100644
new mode 100755
index 29dedf5..ce10445
--- a/test/testdata/htdocs.expected/summary/test-d.html
+++ b/test/testdata/htdocs.expected/summary/test-d.html
@@ -22,7 +22,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0.42590-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/test-d/test-d-1.0.42590-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0.42590-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../noarch/test-d/test-d-1.0.42590-1">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/test-e-src.html b/test/testdata/htdocs.expected/summary/test-e-src.html
index 798e28d..e307615 100755
--- a/test/testdata/htdocs.expected/summary/test-e-src.html
+++ b/test/testdata/htdocs.expected/summary/test-e-src.html
@@ -22,7 +22,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/test-e-src/test-e-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/test-e-src/test-e-1.0-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/test-e.html b/test/testdata/htdocs.expected/summary/test-e.html
old mode 100644
new mode 100755
index 63e16f2..7eb1b5f
--- a/test/testdata/htdocs.expected/summary/test-e.html
+++ b/test/testdata/htdocs.expected/summary/test-e.html
@@ -22,7 +22,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/test-e/test-e-1.0-1">list of files</a>]</td><td>stable</td></tr>
+<tr><td>1.0-1</td><td>noarch</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../noarch/test-e/test-e-1.0-1">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/testpackage-src.html b/test/testdata/htdocs.expected/summary/testpackage-src.html
index 152870c..90e2fe0 100755
--- a/test/testdata/htdocs.expected/summary/testpackage-src.html
+++ b/test/testdata/htdocs.expected/summary/testpackage-src.html
@@ -21,7 +21,7 @@
 </table><br>
 <table class="pkgtable">
 <tr><th>Version</th><th>Arch</th><th>Package Size</th><th>Date</th><th>Files</th><th>Status</th></tr>
-<tr><td>0.1-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../x86_64/testpackage-src/testpackage-0.1-1-src">list of files</a>]</td><td>stable</td></tr>
+<tr><td>0.1-1</td><td>src</td><td class="right">1 KiB</td><td>2018-03-02 00:00</td><td>[<a href="../src/testpackage-src/testpackage-0.1-1-src">list of files</a>]</td><td>stable</td></tr>
 </table><br>
 </div>
 </body>
diff --git a/test/testdata/htdocs.expected/summary/testpackage.html b/test/testdata/htdocs.expected/summary/testpackage.html
old mode 100644
new mode 100755
diff --git a/test/testdata/htdocs.expected/x86/.htaccess b/test/testdata/htdocs.expected/x86/.htaccess
deleted file mode 100644
index 1ea7b18..0000000
--- a/test/testdata/htdocs.expected/x86/.htaccess
+++ /dev/null
@@ -1 +0,0 @@
-Redirect temp /packages/x86/index.html https://cygwin.com/packages/package_list.html
diff --git a/test/testdata/htdocs.expected/x86_64/arc-src/.htaccess b/test/testdata/htdocs.expected/x86_64/arc-src/.htaccess
deleted file mode 100644
index f6b0a8c..0000000
--- a/test/testdata/htdocs.expected/x86_64/arc-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/arc-src/$ /packages/summary/arc-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/arc/.htaccess b/test/testdata/htdocs.expected/x86_64/arc/.htaccess
index d60d6e2..3a4e4e9 100644
--- a/test/testdata/htdocs.expected/x86_64/arc/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/arc/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/arc/$ /packages/summary/arc.html
+RedirectMatch temp /packages/src/arc/$ /packages/summary/arc.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/arc/arc-4.32.7-10-src b/test/testdata/htdocs.expected/x86_64/arc/arc-4.32.7-10-src
deleted file mode 100644
index ed4f8d3..0000000
--- a/test/testdata/htdocs.expected/x86_64/arc/arc-4.32.7-10-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>arc: The ARC archive utility (source code)</title>
-</head>
-<body>
-<h1>arc: The ARC archive utility (source code)</h1>
-<pre>
-    2016-11-24 22:47        1786 cc1BOI4Z
-    2016-11-24 18:14        1786 ccbdRcNC
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/base-cygwin/.htaccess b/test/testdata/htdocs.expected/x86_64/base-cygwin/.htaccess
index c78b3ea..ac98f29 100644
--- a/test/testdata/htdocs.expected/x86_64/base-cygwin/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/base-cygwin/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/base-cygwin/$ /packages/summary/base-cygwin.html
+RedirectMatch temp /packages/src/base-cygwin/$ /packages/summary/base-cygwin.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/corrupt-src/.htaccess b/test/testdata/htdocs.expected/x86_64/corrupt-src/.htaccess
deleted file mode 100644
index 42d4188..0000000
--- a/test/testdata/htdocs.expected/x86_64/corrupt-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/corrupt-src/$ /packages/summary/corrupt-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/corrupt/.htaccess b/test/testdata/htdocs.expected/x86_64/corrupt/.htaccess
index ab88a1e..c2317ac 100644
--- a/test/testdata/htdocs.expected/x86_64/corrupt/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/corrupt/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/corrupt/$ /packages/summary/corrupt.html
+RedirectMatch temp /packages/src/corrupt/$ /packages/summary/corrupt.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/corrupt/corrupt-2.0.0-1-src b/test/testdata/htdocs.expected/x86_64/corrupt/corrupt-2.0.0-1-src
deleted file mode 100644
index ebbb2e4..0000000
--- a/test/testdata/htdocs.expected/x86_64/corrupt/corrupt-2.0.0-1-src
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>corrupt: A corrupt package (source code)</title>
-</head>
-<body>
-<h1>corrupt: A corrupt package (source code)</h1>
-<pre>
-    2016-06-11 10:34           0 perl-Business-ISBN-2.011-1.src/
-    2016-06-11 10:34      364175 perl-Business-ISBN-2.011-1.src/Business-ISBN-2.011.tar.gz
-package is corrupted
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin-debuginfo/.htaccess b/test/testdata/htdocs.expected/x86_64/cygwin-debuginfo/.htaccess
index 697578c..76d4a43 100644
--- a/test/testdata/htdocs.expected/x86_64/cygwin-debuginfo/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/cygwin-debuginfo/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/cygwin-debuginfo/$ /packages/summary/cygwin-debuginfo.html
+RedirectMatch temp /packages/src/cygwin-debuginfo/$ /packages/summary/cygwin-debuginfo.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin-devel/.htaccess b/test/testdata/htdocs.expected/x86_64/cygwin-devel/.htaccess
index 7f81ddf..4537421 100644
--- a/test/testdata/htdocs.expected/x86_64/cygwin-devel/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/cygwin-devel/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/cygwin-devel/$ /packages/summary/cygwin-devel.html
+RedirectMatch temp /packages/src/cygwin-devel/$ /packages/summary/cygwin-devel.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin-src/.htaccess b/test/testdata/htdocs.expected/x86_64/cygwin-src/.htaccess
deleted file mode 100644
index 8b1dae6..0000000
--- a/test/testdata/htdocs.expected/x86_64/cygwin-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/cygwin-src/$ /packages/summary/cygwin-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin/.htaccess b/test/testdata/htdocs.expected/x86_64/cygwin/.htaccess
index a401464..9dac093 100644
--- a/test/testdata/htdocs.expected/x86_64/cygwin/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/cygwin/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/cygwin/$ /packages/summary/cygwin.html
+RedirectMatch temp /packages/src/cygwin/$ /packages/summary/cygwin.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.2.0-1-src b/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.2.0-1-src
deleted file mode 100644
index 0f33e5c..0000000
--- a/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.2.0-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>cygwin: The UNIX emulation engine (source code)</title>
-</head>
-<body>
-<h1>cygwin: The UNIX emulation engine (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.2.1-1-src b/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.2.1-1-src
deleted file mode 100644
index 0f33e5c..0000000
--- a/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.2.1-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>cygwin: The UNIX emulation engine (source code)</title>
-</head>
-<body>
-<h1>cygwin: The UNIX emulation engine (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.3.0-0.3-src b/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.3.0-0.3-src
deleted file mode 100644
index 0f33e5c..0000000
--- a/test/testdata/htdocs.expected/x86_64/cygwin/cygwin-2.3.0-0.3-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>cygwin: The UNIX emulation engine (source code)</title>
-</head>
-<body>
-<h1>cygwin: The UNIX emulation engine (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/keychain-src/.htaccess b/test/testdata/htdocs.expected/x86_64/keychain-src/.htaccess
deleted file mode 100644
index d9d0524..0000000
--- a/test/testdata/htdocs.expected/x86_64/keychain-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/keychain-src/$ /packages/summary/keychain-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/keychain/.htaccess b/test/testdata/htdocs.expected/x86_64/keychain/.htaccess
index 493c769..1872e4c 100644
--- a/test/testdata/htdocs.expected/x86_64/keychain/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/keychain/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/keychain/$ /packages/summary/keychain.html
+RedirectMatch temp /packages/src/keychain/$ /packages/summary/keychain.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/keychain/keychain-2.6.8-1-src b/test/testdata/htdocs.expected/x86_64/keychain/keychain-2.6.8-1-src
deleted file mode 100644
index 00b76f8..0000000
--- a/test/testdata/htdocs.expected/x86_64/keychain/keychain-2.6.8-1-src
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>keychain: Key manager for OpenSSH (source code)</title>
-</head>
-<body>
-<h1>keychain: Key manager for OpenSSH (source code)</h1>
-<pre>
-    2006-11-09 04:59        3051 keychain-2.6.8-1.patch
-    2006-11-09 04:59        5621 keychain-2.6.8-1.sh
-    2006-11-09 04:59       31531 keychain-2.6.8.tar.bz2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/keychain/keychain-2.7.1-1-src b/test/testdata/htdocs.expected/x86_64/keychain/keychain-2.7.1-1-src
deleted file mode 100644
index 808380d..0000000
--- a/test/testdata/htdocs.expected/x86_64/keychain/keychain-2.7.1-1-src
+++ /dev/null
@@ -1,16 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>keychain: Key manager for OpenSSH (source code)</title>
-</head>
-<body>
-<h1>keychain: Key manager for OpenSSH (source code)</h1>
-<pre>
-    2012-10-10 05:40       24455 keychain-2.7.1-1-cygwin.patch
-    2012-10-10 05:40         270 keychain-2.7.1-1-cygwin.patch.sig
-    2012-10-10 05:40      320093 keychain-2.7.1-1.sh
-    2012-10-10 05:40         260 keychain-2.7.1-1.sh.sig
-    2012-10-10 05:40       65211 keychain_2.7.1.orig.tar.gz
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/libdns_sd-devel/.htaccess b/test/testdata/htdocs.expected/x86_64/libdns_sd-devel/.htaccess
index 32a34ee..e43579e 100644
--- a/test/testdata/htdocs.expected/x86_64/libdns_sd-devel/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/libdns_sd-devel/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/libdns_sd-devel/$ /packages/summary/libdns_sd-devel.html
+RedirectMatch temp /packages/src/libdns_sd-devel/$ /packages/summary/libdns_sd-devel.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/libdns_sd1/.htaccess b/test/testdata/htdocs.expected/x86_64/libdns_sd1/.htaccess
index 3ff606d..46bdc88 100644
--- a/test/testdata/htdocs.expected/x86_64/libdns_sd1/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/libdns_sd1/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/libdns_sd1/$ /packages/summary/libdns_sd1.html
+RedirectMatch temp /packages/src/libdns_sd1/$ /packages/summary/libdns_sd1.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/libtextcat-devel/.htaccess b/test/testdata/htdocs.expected/x86_64/libtextcat-devel/.htaccess
deleted file mode 100644
index 3196d64..0000000
--- a/test/testdata/htdocs.expected/x86_64/libtextcat-devel/.htaccess
+++ /dev/null
@@ -1,3 +0,0 @@
-Options Indexes
-IndexOptions -FancyIndexing
-AddType text/html 1 2 3 4 5 6 7 8 9
diff --git a/test/testdata/htdocs.expected/x86_64/libtextcat-devel/libtextcat-devel-2.2-2 b/test/testdata/htdocs.expected/x86_64/libtextcat-devel/libtextcat-devel-2.2-2
deleted file mode 100644
index 03d1ee6..0000000
--- a/test/testdata/htdocs.expected/x86_64/libtextcat-devel/libtextcat-devel-2.2-2
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
-<h1>libtextcat-devel: Helper, header and library for libtextcat (installed binaries and support files)</h1>
-<tt><pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre></tt>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/libtextcat0/.htaccess b/test/testdata/htdocs.expected/x86_64/libtextcat0/.htaccess
deleted file mode 100644
index 3196d64..0000000
--- a/test/testdata/htdocs.expected/x86_64/libtextcat0/.htaccess
+++ /dev/null
@@ -1,3 +0,0 @@
-Options Indexes
-IndexOptions -FancyIndexing
-AddType text/html 1 2 3 4 5 6 7 8 9
diff --git a/test/testdata/htdocs.expected/x86_64/libtextcat0/libtextcat0-2.2-2 b/test/testdata/htdocs.expected/x86_64/libtextcat0/libtextcat0-2.2-2
deleted file mode 100644
index 076ed7a..0000000
--- a/test/testdata/htdocs.expected/x86_64/libtextcat0/libtextcat0-2.2-2
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
-<h1>libtextcat0: Text Classification Library dll (installed binaries and support files)</h1>
-<tt><pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre></tt>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/mDNSResponder-src/.htaccess b/test/testdata/htdocs.expected/x86_64/mDNSResponder-src/.htaccess
deleted file mode 100644
index ba4831c..0000000
--- a/test/testdata/htdocs.expected/x86_64/mDNSResponder-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/mDNSResponder-src/$ /packages/summary/mDNSResponder-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/mDNSResponder/.htaccess b/test/testdata/htdocs.expected/x86_64/mDNSResponder/.htaccess
index 1e135f1..294d035 100644
--- a/test/testdata/htdocs.expected/x86_64/mDNSResponder/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/mDNSResponder/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/mDNSResponder/$ /packages/summary/mDNSResponder.html
+RedirectMatch temp /packages/src/mDNSResponder/$ /packages/summary/mDNSResponder.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/mDNSResponder/mDNSResponder-379.32.1-1-src b/test/testdata/htdocs.expected/x86_64/mDNSResponder/mDNSResponder-379.32.1-1-src
deleted file mode 100644
index a0781ca..0000000
--- a/test/testdata/htdocs.expected/x86_64/mDNSResponder/mDNSResponder-379.32.1-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>mDNSResponder: Bonjour Zeroconf implementation (source code)</title>
-</head>
-<body>
-<h1>mDNSResponder: Bonjour Zeroconf implementation (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/naim/.htaccess b/test/testdata/htdocs.expected/x86_64/naim/.htaccess
deleted file mode 100644
index 3196d64..0000000
--- a/test/testdata/htdocs.expected/x86_64/naim/.htaccess
+++ /dev/null
@@ -1,3 +0,0 @@
-Options Indexes
-IndexOptions -FancyIndexing
-AddType text/html 1 2 3 4 5 6 7 8 9
diff --git a/test/testdata/htdocs.expected/x86_64/obs-a-src/.htaccess b/test/testdata/htdocs.expected/x86_64/obs-a-src/.htaccess
deleted file mode 100644
index 0b84073..0000000
--- a/test/testdata/htdocs.expected/x86_64/obs-a-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/obs-a-src/$ /packages/summary/obs-a-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-a/.htaccess b/test/testdata/htdocs.expected/x86_64/obs-a/.htaccess
deleted file mode 100644
index 7d7cfb3..0000000
--- a/test/testdata/htdocs.expected/x86_64/obs-a/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/obs-a/$ /packages/summary/obs-a.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-a/obs-a-1.0-1-src b/test/testdata/htdocs.expected/x86_64/obs-a/obs-a-1.0-1-src
deleted file mode 100644
index 9bb71f6..0000000
--- a/test/testdata/htdocs.expected/x86_64/obs-a/obs-a-1.0-1-src
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>obs-a: obsolete package A (source code)</title>
-</head>
-<body>
-<h1>obs-a: obsolete package A (source code)</h1>
-<pre>
-    2017-05-22 13:04          82 test-a-1.0-1.hint
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/obs-b-src/.htaccess b/test/testdata/htdocs.expected/x86_64/obs-b-src/.htaccess
deleted file mode 100644
index a400931..0000000
--- a/test/testdata/htdocs.expected/x86_64/obs-b-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/obs-b-src/$ /packages/summary/obs-b-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-b/.htaccess b/test/testdata/htdocs.expected/x86_64/obs-b/.htaccess
deleted file mode 100644
index 7a44be8..0000000
--- a/test/testdata/htdocs.expected/x86_64/obs-b/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/obs-b/$ /packages/summary/obs-b.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/obs-b/obs-b-1.0-1-src b/test/testdata/htdocs.expected/x86_64/obs-b/obs-b-1.0-1-src
deleted file mode 100644
index 7862528..0000000
--- a/test/testdata/htdocs.expected/x86_64/obs-b/obs-b-1.0-1-src
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>obs-b: obsolete package B (source code)</title>
-</head>
-<body>
-<h1>obs-b: obsolete package B (source code)</h1>
-<pre>
-    2017-05-22 13:04          82 test-a-1.0-1.hint
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/openssh-src/.htaccess b/test/testdata/htdocs.expected/x86_64/openssh-src/.htaccess
deleted file mode 100644
index 454cc2c..0000000
--- a/test/testdata/htdocs.expected/x86_64/openssh-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/openssh-src/$ /packages/summary/openssh-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/openssh/.htaccess b/test/testdata/htdocs.expected/x86_64/openssh/.htaccess
index 85f25b7..6eb8a33 100644
--- a/test/testdata/htdocs.expected/x86_64/openssh/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/openssh/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/openssh/$ /packages/summary/openssh.html
+RedirectMatch temp /packages/src/openssh/$ /packages/summary/openssh.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/openssh/openssh-7.2p2-1-src b/test/testdata/htdocs.expected/x86_64/openssh/openssh-7.2p2-1-src
deleted file mode 100644
index e88e82c..0000000
--- a/test/testdata/htdocs.expected/x86_64/openssh/openssh-7.2p2-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>openssh: The OpenSSH server and client programs (source code)</title>
-</head>
-<body>
-<h1>openssh: The OpenSSH server and client programs (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only-src/.htaccess b/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only-src/.htaccess
deleted file mode 100644
index b9fef64..0000000
--- a/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/per-version-replacement-hint-only-src/$ /packages/summary/per-version-replacement-hint-only-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only/.htaccess b/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only/.htaccess
index d01b94d..b88b2c5 100644
--- a/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/per-version-replacement-hint-only/$ /packages/summary/per-version-replacement-hint-only.html
+RedirectMatch temp /packages/src/per-version-replacement-hint-only/$ /packages/summary/per-version-replacement-hint-only.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only/per-version-replacement-hint-only-1.0-1-src b/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only/per-version-replacement-hint-only-1.0-1-src
deleted file mode 100644
index 588d9af..0000000
--- a/test/testdata/htdocs.expected/x86_64/per-version-replacement-hint-only/per-version-replacement-hint-only-1.0-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>per-version-replacement-hint-only: Per-version hint test package (source code)</title>
-</head>
-<body>
-<h1>per-version-replacement-hint-only: Per-version hint test package (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/per-version-src/.htaccess b/test/testdata/htdocs.expected/x86_64/per-version-src/.htaccess
deleted file mode 100644
index bcfded8..0000000
--- a/test/testdata/htdocs.expected/x86_64/per-version-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/per-version-src/$ /packages/summary/per-version-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/per-version/.htaccess b/test/testdata/htdocs.expected/x86_64/per-version/.htaccess
index 6486bbe..cf0887b 100644
--- a/test/testdata/htdocs.expected/x86_64/per-version/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/per-version/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/per-version/$ /packages/summary/per-version.html
+RedirectMatch temp /packages/src/per-version/$ /packages/summary/per-version.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/per-version/per-version-4.0-1-src b/test/testdata/htdocs.expected/x86_64/per-version/per-version-4.0-1-src
deleted file mode 100644
index e123057..0000000
--- a/test/testdata/htdocs.expected/x86_64/per-version/per-version-4.0-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>per-version: Per-version hint test package (source code)</title>
-</head>
-<body>
-<h1>per-version: Per-version hint test package (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/per-version/per-version-4.8-1-src b/test/testdata/htdocs.expected/x86_64/per-version/per-version-4.8-1-src
deleted file mode 100644
index e123057..0000000
--- a/test/testdata/htdocs.expected/x86_64/per-version/per-version-4.8-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>per-version: Per-version hint test package (source code)</title>
-</head>
-<body>
-<h1>per-version: Per-version hint test package (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/.htaccess b/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/.htaccess
deleted file mode 100644
index 7d9395a..0000000
--- a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/perl-Net-SMTP-SSL-src/$ /packages/summary/perl-Net-SMTP-SSL-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/.htaccess b/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/.htaccess
deleted file mode 100644
index 30662d1..0000000
--- a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/perl-Net-SMTP-SSL/$ /packages/summary/perl-Net-SMTP-SSL.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1-src b/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1-src
deleted file mode 100644
index 7968fa7..0000000
--- a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.01-1-src
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>perl-Net-SMTP-SSL: Perl distribution Net-SMTP-SSL (source code)</title>
-</head>
-<body>
-<h1>perl-Net-SMTP-SSL: Perl distribution Net-SMTP-SSL (source code)</h1>
-<pre>
-    2015-06-26 19:10           0 perl-Net-SMTP-SSL-1.03-1.src/
-    2015-06-26 19:10        2271 perl-Net-SMTP-SSL-1.03-1.src/Net-SMTP-SSL-1.03.tar.gz
-    2015-06-26 19:10         296 perl-Net-SMTP-SSL-1.03-1.src/perl-Net-SMTP-SSL.cygport
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1-src b/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1-src
deleted file mode 100644
index 7968fa7..0000000
--- a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.02-1-src
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>perl-Net-SMTP-SSL: Perl distribution Net-SMTP-SSL (source code)</title>
-</head>
-<body>
-<h1>perl-Net-SMTP-SSL: Perl distribution Net-SMTP-SSL (source code)</h1>
-<pre>
-    2015-06-26 19:10           0 perl-Net-SMTP-SSL-1.03-1.src/
-    2015-06-26 19:10        2271 perl-Net-SMTP-SSL-1.03-1.src/Net-SMTP-SSL-1.03.tar.gz
-    2015-06-26 19:10         296 perl-Net-SMTP-SSL-1.03-1.src/perl-Net-SMTP-SSL.cygport
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1-src b/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1-src
deleted file mode 100644
index 7968fa7..0000000
--- a/test/testdata/htdocs.expected/x86_64/perl-Net-SMTP-SSL/perl-Net-SMTP-SSL-1.03-1-src
+++ /dev/null
@@ -1,14 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>perl-Net-SMTP-SSL: Perl distribution Net-SMTP-SSL (source code)</title>
-</head>
-<body>
-<h1>perl-Net-SMTP-SSL: Perl distribution Net-SMTP-SSL (source code)</h1>
-<pre>
-    2015-06-26 19:10           0 perl-Net-SMTP-SSL-1.03-1.src/
-    2015-06-26 19:10        2271 perl-Net-SMTP-SSL-1.03-1.src/Net-SMTP-SSL-1.03.tar.gz
-    2015-06-26 19:10         296 perl-Net-SMTP-SSL-1.03-1.src/perl-Net-SMTP-SSL.cygport
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/proj-debuginfo/.htaccess b/test/testdata/htdocs.expected/x86_64/proj-debuginfo/.htaccess
deleted file mode 100644
index 3196d64..0000000
--- a/test/testdata/htdocs.expected/x86_64/proj-debuginfo/.htaccess
+++ /dev/null
@@ -1,3 +0,0 @@
-Options Indexes
-IndexOptions -FancyIndexing
-AddType text/html 1 2 3 4 5 6 7 8 9
diff --git a/test/testdata/htdocs.expected/x86_64/proj-debuginfo/proj-debuginfo-4.8.0-1 b/test/testdata/htdocs.expected/x86_64/proj-debuginfo/proj-debuginfo-4.8.0-1
deleted file mode 100644
index d8a0fc4..0000000
--- a/test/testdata/htdocs.expected/x86_64/proj-debuginfo/proj-debuginfo-4.8.0-1
+++ /dev/null
@@ -1,7 +0,0 @@
-<html>
-<h1>proj-debuginfo: Debug info for proj (installed binaries and support files)</h1>
-<tt><pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre></tt>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/rpm-doc-src/.htaccess b/test/testdata/htdocs.expected/x86_64/rpm-doc-src/.htaccess
deleted file mode 100644
index afea2d3..0000000
--- a/test/testdata/htdocs.expected/x86_64/rpm-doc-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/rpm-doc-src/$ /packages/summary/rpm-doc-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/rpm-doc/.htaccess b/test/testdata/htdocs.expected/x86_64/rpm-doc/.htaccess
index bd25abd..f56e906 100644
--- a/test/testdata/htdocs.expected/x86_64/rpm-doc/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/rpm-doc/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/rpm-doc/$ /packages/summary/rpm-doc.html
+RedirectMatch temp /packages/src/rpm-doc/$ /packages/summary/rpm-doc.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/rpm-doc/rpm-doc-4.1-2-src b/test/testdata/htdocs.expected/x86_64/rpm-doc/rpm-doc-4.1-2-src
deleted file mode 100644
index c810de5..0000000
--- a/test/testdata/htdocs.expected/x86_64/rpm-doc/rpm-doc-4.1-2-src
+++ /dev/null
@@ -1,11 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>rpm-doc: Obsolete package for RPM package management system manual pages (extra text to so repr is not one line) (source code)</title>
-</head>
-<body>
-<h1>rpm-doc: Obsolete package for RPM package management system manual pages (extra text to so repr is not one line) (source code)</h1>
-<pre>
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion-src/.htaccess b/test/testdata/htdocs.expected/x86_64/staleversion-src/.htaccess
deleted file mode 100644
index 223261d..0000000
--- a/test/testdata/htdocs.expected/x86_64/staleversion-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/staleversion-src/$ /packages/summary/staleversion-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion/.htaccess b/test/testdata/htdocs.expected/x86_64/staleversion/.htaccess
index 3a5a5d8..77a5a79 100644
--- a/test/testdata/htdocs.expected/x86_64/staleversion/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/staleversion/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/staleversion/$ /packages/summary/staleversion.html
+RedirectMatch temp /packages/src/staleversion/$ /packages/summary/staleversion.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-240-1-src b/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-240-1-src
deleted file mode 100644
index 1281b1c..0000000
--- a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-240-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>staleversion: Test package for stale version removal (source code)</title>
-</head>
-<body>
-<h1>staleversion: Test package for stale version removal (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-242-0-src b/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-242-0-src
deleted file mode 100644
index 1281b1c..0000000
--- a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-242-0-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>staleversion: Test package for stale version removal (source code)</title>
-</head>
-<body>
-<h1>staleversion: Test package for stale version removal (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-243-0-src b/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-243-0-src
deleted file mode 100644
index 1281b1c..0000000
--- a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-243-0-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>staleversion: Test package for stale version removal (source code)</title>
-</head>
-<body>
-<h1>staleversion: Test package for stale version removal (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-250-0-src b/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-250-0-src
deleted file mode 100644
index 1281b1c..0000000
--- a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-250-0-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>staleversion: Test package for stale version removal (source code)</title>
-</head>
-<body>
-<h1>staleversion: Test package for stale version removal (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-251-0-src b/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-251-0-src
deleted file mode 100644
index 1281b1c..0000000
--- a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-251-0-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>staleversion: Test package for stale version removal (source code)</title>
-</head>
-<body>
-<h1>staleversion: Test package for stale version removal (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-260-0-src b/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-260-0-src
deleted file mode 100644
index 1281b1c..0000000
--- a/test/testdata/htdocs.expected/x86_64/staleversion/staleversion-260-0-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>staleversion: Test package for stale version removal (source code)</title>
-</head>
-<body>
-<h1>staleversion: Test package for stale version removal (source code)</h1>
-<pre>
-    2015-10-11 14:45          26 test/test.1
-    2015-10-11 14:45          31 test/test.2
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/test-c-src/.htaccess b/test/testdata/htdocs.expected/x86_64/test-c-src/.htaccess
deleted file mode 100644
index 3a6cda7..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-c-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/test-c-src/$ /packages/summary/test-c-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-c/.htaccess b/test/testdata/htdocs.expected/x86_64/test-c/.htaccess
deleted file mode 100644
index 6a259a6..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-c/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/test-c/$ /packages/summary/test-c.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-c/test-c-1.0-1-src b/test/testdata/htdocs.expected/x86_64/test-c/test-c-1.0-1-src
deleted file mode 100644
index ae1aaff..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-c/test-c-1.0-1-src
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>test-c: test package C (source code)</title>
-</head>
-<body>
-<h1>test-c: test package C (source code)</h1>
-<pre>
-    2017-05-22 13:27          82 test-c-0.5-1.hint
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/test-d-src/.htaccess b/test/testdata/htdocs.expected/x86_64/test-d-src/.htaccess
deleted file mode 100644
index ccad7c2..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-d-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/test-d-src/$ /packages/summary/test-d-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-d/.htaccess b/test/testdata/htdocs.expected/x86_64/test-d/.htaccess
deleted file mode 100644
index 27b0b34..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-d/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/test-d/$ /packages/summary/test-d.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-d/test-d-1.0.42590-1-src b/test/testdata/htdocs.expected/x86_64/test-d/test-d-1.0.42590-1-src
deleted file mode 100644
index 655f79c..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-d/test-d-1.0.42590-1-src
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>test-d: test package D (source code)</title>
-</head>
-<body>
-<h1>test-d: test package D (source code)</h1>
-<pre>
-    2017-05-22 18:17          40 test-d-1.0-1.hint
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/test-e-src/.htaccess b/test/testdata/htdocs.expected/x86_64/test-e-src/.htaccess
deleted file mode 100644
index 71e2bac..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-e-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/test-e-src/$ /packages/summary/test-e-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-e/.htaccess b/test/testdata/htdocs.expected/x86_64/test-e/.htaccess
deleted file mode 100644
index dbd0a7d..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-e/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/test-e/$ /packages/summary/test-e.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/test-e/test-e-1.0-1-src b/test/testdata/htdocs.expected/x86_64/test-e/test-e-1.0-1-src
deleted file mode 100644
index 8e0d879..0000000
--- a/test/testdata/htdocs.expected/x86_64/test-e/test-e-1.0-1-src
+++ /dev/null
@@ -1,12 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>test-e: test package E (source code)</title>
-</head>
-<body>
-<h1>test-e: test package E (source code)</h1>
-<pre>
-    2017-05-22 18:17          40 test-d-1.0-1.hint
-</pre>
-</body>
-</html>
diff --git a/test/testdata/htdocs.expected/x86_64/testpackage-src/.htaccess b/test/testdata/htdocs.expected/x86_64/testpackage-src/.htaccess
deleted file mode 100644
index f3e4385..0000000
--- a/test/testdata/htdocs.expected/x86_64/testpackage-src/.htaccess
+++ /dev/null
@@ -1,2 +0,0 @@
-RedirectMatch temp /packages/x86_64/testpackage-src/$ /packages/summary/testpackage-src.html
-ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/testpackage/.htaccess b/test/testdata/htdocs.expected/x86_64/testpackage/.htaccess
index d5b6c9f..006fb27 100644
--- a/test/testdata/htdocs.expected/x86_64/testpackage/.htaccess
+++ b/test/testdata/htdocs.expected/x86_64/testpackage/.htaccess
@@ -1,2 +1,2 @@
-RedirectMatch temp /packages/x86_64/testpackage/$ /packages/summary/testpackage.html
+RedirectMatch temp /packages/src/testpackage/$ /packages/summary/testpackage.html
 ForceType text/html
diff --git a/test/testdata/htdocs.expected/x86_64/testpackage/testpackage-0.1-1-src b/test/testdata/htdocs.expected/x86_64/testpackage/testpackage-0.1-1-src
deleted file mode 100644
index e661c57..0000000
--- a/test/testdata/htdocs.expected/x86_64/testpackage/testpackage-0.1-1-src
+++ /dev/null
@@ -1,13 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-<title>testpackage: A test package (stuff &amp; other stuff) (source code)</title>
-</head>
-<body>
-<h1>testpackage: A test package (stuff &amp; other stuff) (source code)</h1>
-<pre>
-    2016-11-24 22:47        1786 cc1BOI4Z
-    2016-11-24 18:14        1786 ccbdRcNC
-</pre>
-</body>
-</html>
diff --git a/test/testdata/process_arch/htdocs.expected b/test/testdata/process_arch/htdocs.expected
index e38d005..a9c0afb 100644
--- a/test/testdata/process_arch/htdocs.expected
+++ b/test/testdata/process_arch/htdocs.expected
@@ -1,6 +1,16 @@
 {'.': ['calm.db', 'packages.inc', 'packages_docs.inc', 'reports_list.inc', 'src_packages.inc'],
  'doc': ['.htaccess'],
  'doc/keychain': ['keychain.README'],
+ 'noarch': ['.htaccess'],
+ 'noarch/obs-a': ['.htaccess', 'obs-a-1.0-1'],
+ 'noarch/obs-b': ['.htaccess', 'obs-b-1.0-1'],
+ 'noarch/perl-Net-SMTP-SSL': ['.htaccess',
+                              'perl-Net-SMTP-SSL-1.02-1',
+                              'perl-Net-SMTP-SSL-1.03-1',
+                              'perl-Net-SMTP-SSL-1.03-2'],
+ 'noarch/test-c': ['.htaccess', 'test-c-1.0-1'],
+ 'noarch/test-d': ['.htaccess', 'test-d-1.0.42590-1'],
+ 'noarch/test-e': ['.htaccess', 'test-e-1.0-1'],
  'reports': ['deprecated_so.html',
              'maintainer_aaron_schneider.html',
              'maintainer_achim_gratz.html',
@@ -73,6 +83,26 @@
              'ruby_rebuilds.html',
              'unmaintained.html',
              'unstable.html'],
+ 'src': ['.htaccess'],
+ 'src/arc-src': ['.htaccess', 'arc-4.32.7-10-src'],
+ 'src/corrupt-src': ['.htaccess', 'corrupt-2.0.0-1-src'],
+ 'src/cygwin-src': ['.htaccess', 'cygwin-2.2.0-1-src', 'cygwin-2.2.1-1-src', 'cygwin-2.3.0-0.3-src'],
+ 'src/keychain-src': ['.htaccess', 'keychain-2.6.8-1-src', 'keychain-2.7.1-1-src'],
+ 'src/mDNSResponder-src': ['.htaccess', 'mDNSResponder-379.32.1-1-src'],
+ 'src/obs-a-src': ['.htaccess', 'obs-a-1.0-1-src'],
+ 'src/obs-b-src': ['.htaccess', 'obs-b-1.0-1-src'],
+ 'src/openssh-src': ['.htaccess', 'openssh-7.2p2-1-src'],
+ 'src/per-version-replacement-hint-only-src': ['.htaccess', 'per-version-replacement-hint-only-1.0-1-src'],
+ 'src/per-version-src': ['.htaccess', 'per-version-4.0-1-src', 'per-version-4.8-1-src', 'per-version-5.0-1-src'],
+ 'src/perl-Net-SMTP-SSL-src': ['.htaccess',
+                               'perl-Net-SMTP-SSL-1.02-1-src',
+                               'perl-Net-SMTP-SSL-1.03-1-src',
+                               'perl-Net-SMTP-SSL-1.03-2-src'],
+ 'src/staleversion-src': ['.htaccess', 'staleversion-243-0-src', 'staleversion-250-0-src', 'staleversion-260-0-src'],
+ 'src/test-c-src': ['.htaccess', 'test-c-1.0-1-src'],
+ 'src/test-d-src': ['.htaccess', 'test-d-1.0.42590-1-src'],
+ 'src/test-e-src': ['.htaccess', 'test-e-1.0-1-src'],
+ 'src/testpackage-src': ['.htaccess', 'testpackage-1.0-1-src'],
  'summary': ['arc-src.html',
              'arc.html',
              'base-cygwin.html',
@@ -114,50 +144,22 @@
              'testpackage.html'],
  'x86_64': ['.htaccess'],
  'x86_64/arc': ['.htaccess', 'arc-4.32.7-10'],
- 'x86_64/arc-src': ['.htaccess', 'arc-4.32.7-10-src'],
  'x86_64/base-cygwin': ['.htaccess', 'base-cygwin-3.6-1', 'base-cygwin-3.8-1'],
  'x86_64/corrupt': ['.htaccess', 'corrupt-2.0.0-1'],
- 'x86_64/corrupt-src': ['.htaccess', 'corrupt-2.0.0-1-src'],
  'x86_64/cygwin': ['.htaccess', 'cygwin-2.2.0-1', 'cygwin-2.2.1-1', 'cygwin-2.3.0-0.3'],
  'x86_64/cygwin-debuginfo': ['.htaccess',
                              'cygwin-debuginfo-2.2.0-1',
                              'cygwin-debuginfo-2.2.1-1',
                              'cygwin-debuginfo-2.3.0-0.3'],
  'x86_64/cygwin-devel': ['.htaccess', 'cygwin-devel-2.2.0-1', 'cygwin-devel-2.2.1-1', 'cygwin-devel-2.3.0-0.3'],
- 'x86_64/cygwin-src': ['.htaccess', 'cygwin-2.2.0-1-src', 'cygwin-2.2.1-1-src', 'cygwin-2.3.0-0.3-src'],
  'x86_64/keychain': ['.htaccess', 'keychain-2.6.8-1', 'keychain-2.7.1-1'],
- 'x86_64/keychain-src': ['.htaccess', 'keychain-2.6.8-1-src', 'keychain-2.7.1-1-src'],
  'x86_64/libdns_sd-devel': ['.htaccess', 'libdns_sd-devel-379.32.1-1'],
  'x86_64/libdns_sd1': ['.htaccess', 'libdns_sd1-379.32.1-1'],
  'x86_64/mDNSResponder': ['.htaccess', 'mDNSResponder-379.32.1-1'],
- 'x86_64/mDNSResponder-src': ['.htaccess', 'mDNSResponder-379.32.1-1-src'],
- 'x86_64/obs-a': ['.htaccess', 'obs-a-1.0-1'],
- 'x86_64/obs-a-src': ['.htaccess', 'obs-a-1.0-1-src'],
- 'x86_64/obs-b': ['.htaccess', 'obs-b-1.0-1'],
- 'x86_64/obs-b-src': ['.htaccess', 'obs-b-1.0-1-src'],
  'x86_64/openssh': ['.htaccess', 'openssh-7.2p2-1'],
- 'x86_64/openssh-src': ['.htaccess', 'openssh-7.2p2-1-src'],
  'x86_64/per-version': ['.htaccess', 'per-version-4.0-1', 'per-version-4.8-1', 'per-version-5.0-1'],
  'x86_64/per-version-replacement-hint-only': ['.htaccess', 'per-version-replacement-hint-only-1.0-1'],
- 'x86_64/per-version-replacement-hint-only-src': ['.htaccess', 'per-version-replacement-hint-only-1.0-1-src'],
- 'x86_64/per-version-src': ['.htaccess', 'per-version-4.0-1-src', 'per-version-4.8-1-src', 'per-version-5.0-1-src'],
- 'x86_64/perl-Net-SMTP-SSL': ['.htaccess',
-                              'perl-Net-SMTP-SSL-1.02-1',
-                              'perl-Net-SMTP-SSL-1.03-1',
-                              'perl-Net-SMTP-SSL-1.03-2'],
- 'x86_64/perl-Net-SMTP-SSL-src': ['.htaccess',
-                                  'perl-Net-SMTP-SSL-1.02-1-src',
-                                  'perl-Net-SMTP-SSL-1.03-1-src',
-                                  'perl-Net-SMTP-SSL-1.03-2-src'],
  'x86_64/rpm-doc': ['.htaccess', 'rpm-doc-999-1'],
  'x86_64/staleversion': ['.htaccess', 'staleversion-243-0', 'staleversion-250-0', 'staleversion-260-0'],
- 'x86_64/staleversion-src': ['.htaccess', 'staleversion-243-0-src', 'staleversion-250-0-src', 'staleversion-260-0-src'],
- 'x86_64/test-c': ['.htaccess', 'test-c-1.0-1'],
- 'x86_64/test-c-src': ['.htaccess', 'test-c-1.0-1-src'],
- 'x86_64/test-d': ['.htaccess', 'test-d-1.0.42590-1'],
- 'x86_64/test-d-src': ['.htaccess', 'test-d-1.0.42590-1-src'],
- 'x86_64/test-e': ['.htaccess', 'test-e-1.0-1'],
- 'x86_64/test-e-src': ['.htaccess', 'test-e-1.0-1-src'],
  'x86_64/testpackage': ['.htaccess', 'testpackage-1.0-1'],
- 'x86_64/testpackage-src': ['.htaccess', 'testpackage-1.0-1-src'],
  'x86_64/testpackage-subpackage': ['.htaccess', 'testpackage-subpackage-1.0-1']}