[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 & other stuff) (source code)</title>
-</head>
-<body>
-<h1>testpackage: A test package (stuff & 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']}