public inbox for cygwin-apps-cvs@sourceware.org
help / color / mirror / Atom feed
* [calm - Cygwin server-side packaging maintenance script] branch master, updated. df7ae0d55a584fdd03ed01f3f073e8d4e0abf826
@ 2016-03-21 12:31 jturney
0 siblings, 0 replies; only message in thread
From: jturney @ 2016-03-21 12:31 UTC (permalink / raw)
To: cygwin-apps-cvs
https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=df7ae0d55a584fdd03ed01f3f073e8d4e0abf826
commit df7ae0d55a584fdd03ed01f3f073e8d4e0abf826
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date: Mon Mar 21 11:40:37 2016 +0000
Fix buffering_smtp_handler for non-ascii log content
https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=45d1a06888bb883f2857670e04f720339b4883db
commit 45d1a06888bb883f2857670e04f720339b4883db
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date: Fri Mar 18 01:17:41 2016 +0000
Test directory trees are as expected after moving uploads/vaultings
Add a test which verifies that directory trees are as expected after moving
files from uploads to rel_area and from rel_area to vault
https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=52f986d0d1a253204c2a5234a47baa46ddc1be27
commit 52f986d0d1a253204c2a5234a47baa46ddc1be27
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date: Mon Mar 21 11:29:40 2016 +0000
Move calm -> calm.py and add wrapper script
This puts everything into a module, so we can access it easily for testing.
https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=01e3d61d719934b94acb019c6eb601e736088d89
commit 01e3d61d719934b94acb019c6eb601e736088d89
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date: Fri Mar 18 13:52:50 2016 +0000
Fix testdata so validate_packages() can succeed
- add a mock openssh package
- make all libtext packages fail parsing with ldesc embedded quote
- remove proj-debuginfo, since all other proj packages fail parsing
- add rpm-doc-4.1-2-src mock package
- remove unmocked requires of naim packge
Assert that validate_package succeeds
https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=2e8d0f77349fe9e3a7eeaed744954dcadc2c25c9
commit 2e8d0f77349fe9e3a7eeaed744954dcadc2c25c9
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date: Fri Mar 18 00:21:53 2016 +0000
Add a test of deletion cookies
https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=ad0dfa20d33c32d4b12a5c08ed7fa6a576b601cc
commit ad0dfa20d33c32d4b12a5c08ed7fa6a576b601cc
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date: Thu Mar 17 23:10:57 2016 +0000
Sort paths, don't repeat full path for every file moved
This is a cosmetic improvement to reporting
https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/calm.git;h=a04d6b677f047f91620e2de7c3156fdb3020d8b3
commit a04d6b677f047f91620e2de7c3156fdb3020d8b3
Author: Jon Turney <jon.turney@dronecode.org.uk>
Date: Sat Mar 19 11:51:50 2016 +0000
Fix warning about no setup.hint not always being issued
We want to issue this warning in the case of a path like 'release/mintty',
which has one path.sep
Diff:
---
buffering_smtp_handler.py | 18 ++-
calm | 198 +-------------------
calm.py | 195 +++++++++++++++++++
package.py | 2 +-
.../testpackage/testpackage-1.0-1-src.tar.bz2 | Bin 0 -> 195 bytes
.../testpackage/testpackage-subpackage/setup.hint | 2 +-
testdata/htdocs.expected/x86/openssh/.htaccess | 3 +
.../htdocs.expected/x86/openssh/openssh-7.2p2-1 | 7 +
.../x86/openssh/openssh-7.2p2-1-src | 7 +
testdata/htdocs.expected/x86/packages.inc | 4 +-
.../htdocs.expected/x86/rpm-doc/rpm-doc-4.1-2-src | 5 +
testdata/inifile/setup.ini.expected | 16 ++-
testdata/pkglist/cygwin-pkg-maint | 1 +
testdata/pkglist/expected | 2 +-
testdata/process_arch/homedir.expected | 14 ++
testdata/process_arch/htdocs.expected | 24 +++
testdata/process_arch/rel_area.expected | 57 ++++++
testdata/process_arch/vault.expected | 1 +
testdata/uploads/move.expected | 2 +-
testdata/uploads/pkglist.expected | 6 +-
.../release/libtextcat/libtextcat-devel/expected | 10 +-
.../release/libtextcat/libtextcat0/expected | 10 +-
testdata/x86.hints/release/naim/expected | 2 +-
testdata/x86.hints/release/openssh/expected | 5 +
.../release/libtextcat/libtextcat-devel/setup.hint | 7 +
.../x86/release/libtextcat/libtextcat0/setup.hint | 7 +
testdata/x86/release/naim/setup.hint | 2 +-
.../x86/release/openssh/openssh-7.2p2-1-src.tar.xz | Bin 0 -> 228 bytes
.../x86/release/openssh/openssh-7.2p2-1.tar.xz | Bin 0 -> 228 bytes
testdata/x86/release/openssh/setup.hint | 5 +
.../proj-debuginfo/proj-debuginfo-4.8.0-1.tar.xz | Bin 195 -> 0 bytes
.../x86/release/proj/proj-debuginfo/setup.hint | 6 -
.../x86/release/rpm-doc/rpm-doc-4.1-2-src.tar.bz2 | Bin 0 -> 42 bytes
tests.py | 64 ++++++-
uploads.py | 7 +-
35 files changed, 463 insertions(+), 226 deletions(-)
diff --git a/buffering_smtp_handler.py b/buffering_smtp_handler.py
index 16d9bc8..7720588 100644
--- a/buffering_smtp_handler.py
+++ b/buffering_smtp_handler.py
@@ -23,6 +23,7 @@
from contextlib import ExitStack
import logging
import logging.handlers
+import email.message
import common_constants
@@ -46,11 +47,24 @@ class BufferingSMTPHandler(logging.handlers.BufferingHandler):
def flush(self):
if len(self.buffer) > 0:
- msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % (self.fromaddr, ','.join(self.toaddrs), self.subject)
+ msg = ""
for record in self.buffer:
s = self.format(record)
msg = msg + s + "\r\n"
+ m = email.message.Message()
+ m['From'] = self.fromaddr
+ m['To'] = ','.join(self.toaddrs)
+ m['Subject'] = self.subject
+
+ # use utf-8 only if the message can't be ascii encoded
+ charset = 'ascii'
+ try:
+ msg.encode('ascii')
+ except UnicodeError:
+ charset = 'utf-8'
+ m.set_payload(msg, charset=charset)
+
# if toaddrs consists of the single address 'debug', just dump the mail we would have sent
if self.toaddrs == ['debug']:
print('-' * 40)
@@ -63,7 +77,7 @@ class BufferingSMTPHandler(logging.handlers.BufferingHandler):
if not port:
port = smtplib.SMTP_PORT
smtp = smtplib.SMTP(self.mailhost, port)
- smtp.sendmail(self.fromaddr, self.toaddrs, msg)
+ smtp.send_message(m)
smtp.quit()
except:
self.handleError(self.buffer[0]) # first record
diff --git a/calm b/calm
index 9638d9e..ac1524e 100755
--- a/calm
+++ b/calm
@@ -1,195 +1,3 @@
-#!/usr/bin/env python3
-#
-# Copyright (c) 2015 Jon Turney
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to deal
-# in the Software without restriction, including without limitation the rights
-# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-# copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-# THE SOFTWARE.
-#
-
-#
-# calm - better than being upset
-#
-
-#
-# read packages from release area
-# for each maintainer
-# - read and validate any package uploads
-# - build a list of files to move and remove
-# - merge package sets
-# - remove from the package set files which are to be removed
-# - validate merged package set
-# - process remove list
-# - on failure
-# -- mail maintainer with errors
-# -- empty move list
-# -- discard merged package set
-# - on success
-# -- process move list
-# -- mail maintainer with movelist
-# -- continue with merged package set
-# write setup.ini file
-#
-
-import argparse
-import logging
-import os
-import sys
-
-from buffering_smtp_handler import mail_logs
-import common_constants
-import maintainers
-import package
-import pkg2html
-import uploads
-
-
-#
-#
-#
-
-def main(args):
- details = '%s%s' % (args.arch, ',dry-run' if args.dryrun else '')
-
- # send one email per run to leads
- with mail_logs(args.email, toaddrs=args.email, subject='calm messages [%s]' % (details)) as leads_email:
- if args.dryrun:
- logging.warning("--dry-run in effect, nothing will really be done")
-
- # build package list
- packages = package.read_packages(args.rel_area, args.arch)
-
- # validate the package set
- if not package.validate_packages(args, packages):
- logging.error("existing package set has errors, not processing uploads or writing setup.ini")
- return 1
-
- # read maintainer list
- mlist = maintainers.Maintainer.read(args)
-
- # make the list of all packages
- all_packages = maintainers.Maintainer.all_packages(mlist)
-
- # for each maintainer
- for name in sorted(mlist.keys()):
- m = mlist[name]
-
- # also send a mail to each maintainer about their packages
- with mail_logs(args.email, toaddrs=m.email, subject='calm messages for %s [%s]' % (name, details)) as maint_email:
-
- (error, mpackages, to_relarea, to_vault, remove_always, remove_success) = uploads.scan(m, all_packages, args)
-
- uploads.remove(args, remove_always)
-
- # if there are no uploaded packages for this maintainer, we
- # don't have anything to do
- if not mpackages:
- logging.info("nothing to do for maintainer %s" % (name))
- continue
-
- if not error:
- # merge package set
- merged_packages = package.merge(packages, mpackages)
-
- # remove file which are to be removed
- #
- # XXX: this doesn't properly account for removing setup.hint
- # files
- for p in to_vault:
- for f in to_vault[p]:
- package.delete(merged_packages, p, f)
-
- # validate the package set
- if package.validate_packages(args, merged_packages):
- # process the move list
- uploads.move_to_vault(args, to_vault)
- uploads.remove(args, remove_success)
- uploads.move_to_relarea(m, args, to_relarea)
- # use merged package list
- packages = merged_packages
- logging.info("added %d packages from maintainer %s" % (len(mpackages), name))
- else:
- # otherwise we discard move list and merged_packages
- logging.error("error while merging uploaded packages for %s" % (name))
-
- # write setup.ini
- package.write_setup_ini(args, packages)
-
- # update packages listings
- # XXX: perhaps we need a --[no]listing command line option to disable this from being run?
- pkg2html.update_package_listings(args, packages)
-
- return 0
-
-#
-#
-#
-
-if __name__ == "__main__":
- htdocs_default = os.path.join(common_constants.HTDOCS, 'packages')
- homedir_default = common_constants.HOMEDIR
- orphanmaint_default = common_constants.ORPHANMAINT
- pkglist_default = common_constants.PKGMAINT
- relarea_default = common_constants.FTP
- vault_default = common_constants.VAULT
- logdir_default = '/sourceware/cygwin-staging/logs'
-
- parser = argparse.ArgumentParser(description='Upset replacement')
- parser.add_argument('--arch', action='store', required=True, choices=common_constants.ARCHES)
- parser.add_argument('--email', action='store', dest='email', nargs='?', const=common_constants.EMAILS, help='email output to maintainer and ADDRS (default: ' + common_constants.EMAILS + ')', metavar='ADDRS')
- parser.add_argument('--force', action='store_true', help="overwrite existing files")
- parser.add_argument('--homedir', action='store', metavar='DIR', help="maintainer home directory (default: " + homedir_default + ")", default=homedir_default)
- parser.add_argument('--htdocs', action='store', metavar='DIR', help="htdocs output directory (default: " + htdocs_default + ")", default=htdocs_default)
- parser.add_argument('--inifile', '-u', action='store', help='output filename', required=True)
- parser.add_argument('--logdir', action='store', metavar='DIR', help="log directory (default: '" + logdir_default + "')", default=logdir_default)
- parser.add_argument('--orphanmaint', action='store', metavar='NAMES', help="orphan package maintainers (default: '" + orphanmaint_default + "')", default=orphanmaint_default)
- parser.add_argument('--pkglist', action='store', metavar='FILE', help="package maintainer list (default: " + pkglist_default + ")", default=pkglist_default)
- parser.add_argument('--release', action='store', help='value for setup-release key (default: cygwin)', default='cygwin')
- parser.add_argument('--releasearea', action='store', metavar='DIR', help="release directory (default: " + relarea_default + ")", default=relarea_default, dest='rel_area')
- parser.add_argument('--setup-version', action='store', metavar='VERSION', help='value for setup-version key')
- parser.add_argument('-n', '--dry-run', action='store_true', dest='dryrun', help="don't do anything")
- parser.add_argument('--vault', action='store', metavar='DIR', help="vault directory (default: " + vault_default + ")", default=vault_default, dest='vault')
- parser.add_argument('-v', '--verbose', action='count', dest='verbose', help='verbose output')
- (args) = parser.parse_args()
-
- # set up logging to a file
- try:
- os.makedirs(args.logdir, exist_ok=True)
- except FileExistsError:
- pass
- rfh = logging.handlers.RotatingFileHandler(os.path.join(args.logdir, 'calm.log'), backupCount=24)
- rfh.doRollover() # force a rotate on every run
- rfh.setFormatter(logging.Formatter('%(asctime)s - %(levelname)-8s - %(message)s'))
- rfh.setLevel(logging.INFO)
- logging.getLogger().addHandler(rfh)
-
- # setup logging to stdout, of WARNING messages or higher (INFO if verbose)
- ch = logging.StreamHandler(sys.stdout)
- ch.setFormatter(logging.Formatter(os.path.basename(sys.argv[0])+': %(message)s'))
- if args.verbose:
- ch.setLevel(logging.INFO)
- else:
- ch.setLevel(logging.WARNING)
- logging.getLogger().addHandler(ch)
-
- # change root logger level from the default of WARNING
- logging.getLogger().setLevel(logging.INFO)
-
- if args.email:
- args.email = args.email.split(',')
-
- sys.exit(main(args))
+#!/usr/bin/env bash
+base_dir=$(dirname "$0")
+exec python3 "$base_dir/calm.py" "$@"
diff --git a/calm.py b/calm.py
new file mode 100755
index 0000000..9638d9e
--- /dev/null
+++ b/calm.py
@@ -0,0 +1,195 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2015 Jon Turney
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to deal
+# in the Software without restriction, including without limitation the rights
+# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+# copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+# THE SOFTWARE.
+#
+
+#
+# calm - better than being upset
+#
+
+#
+# read packages from release area
+# for each maintainer
+# - read and validate any package uploads
+# - build a list of files to move and remove
+# - merge package sets
+# - remove from the package set files which are to be removed
+# - validate merged package set
+# - process remove list
+# - on failure
+# -- mail maintainer with errors
+# -- empty move list
+# -- discard merged package set
+# - on success
+# -- process move list
+# -- mail maintainer with movelist
+# -- continue with merged package set
+# write setup.ini file
+#
+
+import argparse
+import logging
+import os
+import sys
+
+from buffering_smtp_handler import mail_logs
+import common_constants
+import maintainers
+import package
+import pkg2html
+import uploads
+
+
+#
+#
+#
+
+def main(args):
+ details = '%s%s' % (args.arch, ',dry-run' if args.dryrun else '')
+
+ # send one email per run to leads
+ with mail_logs(args.email, toaddrs=args.email, subject='calm messages [%s]' % (details)) as leads_email:
+ if args.dryrun:
+ logging.warning("--dry-run in effect, nothing will really be done")
+
+ # build package list
+ packages = package.read_packages(args.rel_area, args.arch)
+
+ # validate the package set
+ if not package.validate_packages(args, packages):
+ logging.error("existing package set has errors, not processing uploads or writing setup.ini")
+ return 1
+
+ # read maintainer list
+ mlist = maintainers.Maintainer.read(args)
+
+ # make the list of all packages
+ all_packages = maintainers.Maintainer.all_packages(mlist)
+
+ # for each maintainer
+ for name in sorted(mlist.keys()):
+ m = mlist[name]
+
+ # also send a mail to each maintainer about their packages
+ with mail_logs(args.email, toaddrs=m.email, subject='calm messages for %s [%s]' % (name, details)) as maint_email:
+
+ (error, mpackages, to_relarea, to_vault, remove_always, remove_success) = uploads.scan(m, all_packages, args)
+
+ uploads.remove(args, remove_always)
+
+ # if there are no uploaded packages for this maintainer, we
+ # don't have anything to do
+ if not mpackages:
+ logging.info("nothing to do for maintainer %s" % (name))
+ continue
+
+ if not error:
+ # merge package set
+ merged_packages = package.merge(packages, mpackages)
+
+ # remove file which are to be removed
+ #
+ # XXX: this doesn't properly account for removing setup.hint
+ # files
+ for p in to_vault:
+ for f in to_vault[p]:
+ package.delete(merged_packages, p, f)
+
+ # validate the package set
+ if package.validate_packages(args, merged_packages):
+ # process the move list
+ uploads.move_to_vault(args, to_vault)
+ uploads.remove(args, remove_success)
+ uploads.move_to_relarea(m, args, to_relarea)
+ # use merged package list
+ packages = merged_packages
+ logging.info("added %d packages from maintainer %s" % (len(mpackages), name))
+ else:
+ # otherwise we discard move list and merged_packages
+ logging.error("error while merging uploaded packages for %s" % (name))
+
+ # write setup.ini
+ package.write_setup_ini(args, packages)
+
+ # update packages listings
+ # XXX: perhaps we need a --[no]listing command line option to disable this from being run?
+ pkg2html.update_package_listings(args, packages)
+
+ return 0
+
+#
+#
+#
+
+if __name__ == "__main__":
+ htdocs_default = os.path.join(common_constants.HTDOCS, 'packages')
+ homedir_default = common_constants.HOMEDIR
+ orphanmaint_default = common_constants.ORPHANMAINT
+ pkglist_default = common_constants.PKGMAINT
+ relarea_default = common_constants.FTP
+ vault_default = common_constants.VAULT
+ logdir_default = '/sourceware/cygwin-staging/logs'
+
+ parser = argparse.ArgumentParser(description='Upset replacement')
+ parser.add_argument('--arch', action='store', required=True, choices=common_constants.ARCHES)
+ parser.add_argument('--email', action='store', dest='email', nargs='?', const=common_constants.EMAILS, help='email output to maintainer and ADDRS (default: ' + common_constants.EMAILS + ')', metavar='ADDRS')
+ parser.add_argument('--force', action='store_true', help="overwrite existing files")
+ parser.add_argument('--homedir', action='store', metavar='DIR', help="maintainer home directory (default: " + homedir_default + ")", default=homedir_default)
+ parser.add_argument('--htdocs', action='store', metavar='DIR', help="htdocs output directory (default: " + htdocs_default + ")", default=htdocs_default)
+ parser.add_argument('--inifile', '-u', action='store', help='output filename', required=True)
+ parser.add_argument('--logdir', action='store', metavar='DIR', help="log directory (default: '" + logdir_default + "')", default=logdir_default)
+ parser.add_argument('--orphanmaint', action='store', metavar='NAMES', help="orphan package maintainers (default: '" + orphanmaint_default + "')", default=orphanmaint_default)
+ parser.add_argument('--pkglist', action='store', metavar='FILE', help="package maintainer list (default: " + pkglist_default + ")", default=pkglist_default)
+ parser.add_argument('--release', action='store', help='value for setup-release key (default: cygwin)', default='cygwin')
+ parser.add_argument('--releasearea', action='store', metavar='DIR', help="release directory (default: " + relarea_default + ")", default=relarea_default, dest='rel_area')
+ parser.add_argument('--setup-version', action='store', metavar='VERSION', help='value for setup-version key')
+ parser.add_argument('-n', '--dry-run', action='store_true', dest='dryrun', help="don't do anything")
+ parser.add_argument('--vault', action='store', metavar='DIR', help="vault directory (default: " + vault_default + ")", default=vault_default, dest='vault')
+ parser.add_argument('-v', '--verbose', action='count', dest='verbose', help='verbose output')
+ (args) = parser.parse_args()
+
+ # set up logging to a file
+ try:
+ os.makedirs(args.logdir, exist_ok=True)
+ except FileExistsError:
+ pass
+ rfh = logging.handlers.RotatingFileHandler(os.path.join(args.logdir, 'calm.log'), backupCount=24)
+ rfh.doRollover() # force a rotate on every run
+ rfh.setFormatter(logging.Formatter('%(asctime)s - %(levelname)-8s - %(message)s'))
+ rfh.setLevel(logging.INFO)
+ logging.getLogger().addHandler(rfh)
+
+ # setup logging to stdout, of WARNING messages or higher (INFO if verbose)
+ ch = logging.StreamHandler(sys.stdout)
+ ch.setFormatter(logging.Formatter(os.path.basename(sys.argv[0])+': %(message)s'))
+ if args.verbose:
+ ch.setLevel(logging.INFO)
+ else:
+ ch.setLevel(logging.WARNING)
+ logging.getLogger().addHandler(ch)
+
+ # change root logger level from the default of WARNING
+ logging.getLogger().setLevel(logging.INFO)
+
+ if args.email:
+ args.email = args.email.split(',')
+
+ sys.exit(main(args))
diff --git a/package.py b/package.py
index 1213a67..ef2832c 100755
--- a/package.py
+++ b/package.py
@@ -203,7 +203,7 @@ def read_package(packages, basedir, dirpath, files, strict=False):
if p in past_mistakes.self_source:
packages[p].hints['self-source'] = ''
- elif (len(files) > 0) and (relpath.count(os.path.sep) > 1):
+ elif (len(files) > 0) and (relpath.count(os.path.sep) > 0):
logging.warning("no setup.hint in %s but files: %s" % (dirpath, ', '.join(files)))
if strict:
diff --git a/testdata/homes/Blooey McFooey/x86/release/not-ready/-not-ready-0.9-1.tar.bz2 b/testdata/homes/Blooey McFooey/x86/release/not-ready/-not-ready-0.9-1.tar.bz2
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/homes/Blooey McFooey/x86/release/testpackage/-testpackage-0.1-1.tar.bz2 b/testdata/homes/Blooey McFooey/x86/release/testpackage/-testpackage-0.1-1.tar.bz2
new file mode 100644
index 0000000..e69de29
diff --git a/testdata/homes/Blooey McFooey/x86/release/testpackage/testpackage-1.0-1-src.tar.bz2 b/testdata/homes/Blooey McFooey/x86/release/testpackage/testpackage-1.0-1-src.tar.bz2
new file mode 100644
index 0000000..a1145fb
Binary files /dev/null and b/testdata/homes/Blooey McFooey/x86/release/testpackage/testpackage-1.0-1-src.tar.bz2 differ
diff --git a/testdata/homes/Blooey McFooey/x86/release/testpackage/testpackage-subpackage/setup.hint b/testdata/homes/Blooey McFooey/x86/release/testpackage/testpackage-subpackage/setup.hint
index 74f5a24..90f7384 100644
--- a/testdata/homes/Blooey McFooey/x86/release/testpackage/testpackage-subpackage/setup.hint
+++ b/testdata/homes/Blooey McFooey/x86/release/testpackage/testpackage-subpackage/setup.hint
@@ -1,4 +1,4 @@
sdesc: "A test subpackage"
ldesc: "A test subpackage"
category: Devel
-
+external-source: testpackage
diff --git a/testdata/htdocs.expected/x86/openssh/.htaccess b/testdata/htdocs.expected/x86/openssh/.htaccess
new file mode 100644
index 0000000..3196d64
--- /dev/null
+++ b/testdata/htdocs.expected/x86/openssh/.htaccess
@@ -0,0 +1,3 @@
+Options Indexes
+IndexOptions -FancyIndexing
+AddType text/html 1 2 3 4 5 6 7 8 9
diff --git a/testdata/htdocs.expected/x86/openssh/openssh-7.2p2-1 b/testdata/htdocs.expected/x86/openssh/openssh-7.2p2-1
new file mode 100644
index 0000000..cb2b272
--- /dev/null
+++ b/testdata/htdocs.expected/x86/openssh/openssh-7.2p2-1
@@ -0,0 +1,7 @@
+<html>
+<h1>openssh: The OpenSSH server and client programs (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/testdata/htdocs.expected/x86/openssh/openssh-7.2p2-1-src b/testdata/htdocs.expected/x86/openssh/openssh-7.2p2-1-src
new file mode 100644
index 0000000..e85cbee
--- /dev/null
+++ b/testdata/htdocs.expected/x86/openssh/openssh-7.2p2-1-src
@@ -0,0 +1,7 @@
+<html>
+<h1>openssh: The OpenSSH server and client programs (source code)</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/testdata/htdocs.expected/x86/packages.inc b/testdata/htdocs.expected/x86/packages.inc
index b9b99d6..484f797 100755
--- a/testdata/htdocs.expected/x86/packages.inc
+++ b/testdata/htdocs.expected/x86/packages.inc
@@ -14,10 +14,8 @@
<tr><td><a href="x86/keychain">keychain</a></td><td>Key manager for OpenSSH</td></tr>
<tr><td><a href="x86/libdns_sd-devel">libdns_sd-devel</a></td><td>Bonjour Zeroconf implementation</td></tr>
<tr><td><a href="x86/libdns_sd1">libdns_sd1</a></td><td>Bonjour Zeroconf implementation</td></tr>
-<tr><td><a href="x86/libtextcat-devel">libtextcat-devel</a></td><td>Helper, header and library for libtextcat</td></tr>
-<tr><td><a href="x86/libtextcat0">libtextcat0</a></td><td>Text Classification Library dll</td></tr>
<tr><td><a href="x86/mDNSResponder">mDNSResponder</a></td><td>Bonjour Zeroconf implementation</td></tr>
-<tr><td><a href="x86/proj-debuginfo">proj-debuginfo</a></td><td>Debug info for proj</td></tr>
+<tr><td><a href="x86/openssh">openssh</a></td><td>The OpenSSH server and client programs</td></tr>
<tr><td><a href="x86/rpm-doc">rpm-doc</a></td><td>Obsolete package for RPM package management system manual pages</td></tr>
</table>
</div>
diff --git a/testdata/htdocs.expected/x86/rpm-doc/rpm-doc-4.1-2-src b/testdata/htdocs.expected/x86/rpm-doc/rpm-doc-4.1-2-src
new file mode 100644
index 0000000..3566e39
--- /dev/null
+++ b/testdata/htdocs.expected/x86/rpm-doc/rpm-doc-4.1-2-src
@@ -0,0 +1,5 @@
+<html>
+<h1>rpm-doc: Obsolete package for RPM package management system manual pages (source code)</h1>
+<tt><pre>
+</pre></tt>
+</html>
diff --git a/testdata/inifile/setup.ini.expected b/testdata/inifile/setup.ini.expected
index 0cdb520..6140c5d 100644
--- a/testdata/inifile/setup.ini.expected
+++ b/testdata/inifile/setup.ini.expected
@@ -170,6 +170,18 @@
'a number of popular Windows programs), then you can download it at\n'
'http://support.apple.com/kb/DL999"\n'
'\n'
+ '@ openssh\n'
+ 'sdesc: "The OpenSSH server and client programs"\n'
+ 'ldesc: "OpenSSH is a program for logging into a remote machine and for\n'
+ '\texecuting commands on a remote machine. It can replace rlogin and rsh,\n'
+ '\tproviding encrypted communication between two machines."\n'
+ 'category: Net\n'
+ 'version: 7.2p2-1\n'
+ 'install: x86/release/openssh/openssh-7.2p2-1.tar.xz 228 '
+ 'e675b0ac4bc2c3e1c4971bc56d77b0cd53a9bdf5632873a235d7582e29dfd3e8a7bb04b28f6cdee3e6b3d14c25ed39392538e3f628a9bfda6c905646ebc3c225\n'
+ 'source: x86/release/openssh/openssh-7.2p2-1-src.tar.xz 228 '
+ 'e675b0ac4bc2c3e1c4971bc56d77b0cd53a9bdf5632873a235d7582e29dfd3e8a7bb04b28f6cdee3e6b3d14c25ed39392538e3f628a9bfda6c905646ebc3c225\n'
+ '\n'
'@ rpm-doc\n'
'sdesc: "Obsolete package for RPM package management system manual pages"\n'
'category: _obsolete\n'
@@ -179,4 +191,6 @@
'[prev]\n'
'version: 4.1-2\n'
'install: x86/release/rpm-doc/rpm-doc-4.1-2.tar.bz2 50941 '
- '7cc9db802364252e3206ce9f75c8ca53813d8308a22a425b50ef695dd8e51568740b06739d3aa3399a83fb3d3e1345ab7e2ad03a1e9d47c02dded3363bf4f493\n',)
+ '7cc9db802364252e3206ce9f75c8ca53813d8308a22a425b50ef695dd8e51568740b06739d3aa3399a83fb3d3e1345ab7e2ad03a1e9d47c02dded3363bf4f493\n'
+ 'source: x86/release/rpm-doc/rpm-doc-4.1-2-src.tar.bz2 42 '
+ '28c70b843fe01d90a3eeab4a3617551d236cd0b7d69668d1b1b6c8b14a9fd050e4039c192894c93bdf31575771c58c1fea2a41c24c8da22d10080d8b032b6369\n',)
diff --git a/testdata/pkglist/cygwin-pkg-maint b/testdata/pkglist/cygwin-pkg-maint
index fa639e0..d2375af 100644
--- a/testdata/pkglist/cygwin-pkg-maint
+++ b/testdata/pkglist/cygwin-pkg-maint
@@ -2168,6 +2168,7 @@ telepathy-mission-control Yaakov Selkowitz
telepathy-qt Yaakov Selkowitz
terminus-fonts Yaakov Selkowitz
tesseract-ocr Marco Atzeri
+testpackage Blooey McFooey
tetzle Yaakov Selkowitz
texi2html Dr. Volker Zell
texinfo Ken Brown
diff --git a/testdata/pkglist/expected b/testdata/pkglist/expected
index 199533c..4e8db92 100644
--- a/testdata/pkglist/expected
+++ b/testdata/pkglist/expected
@@ -3,7 +3,7 @@
'Adam Dinwoodie': maintainers.Maintainer('Adam Dinwoodie', [], ['git']),
'Alexey Sokolov': maintainers.Maintainer('Alexey Sokolov', [], ['znc']),
'Andrew Schulman': maintainers.Maintainer('Andrew Schulman', [], ['atool', 'autossh', 'bc', 'discus', 'fish', 'lftp', 'libargp', 'nosleep', 'orpie', 'pinfo', 'ploticus', 'ploticus-doc', 'screen', 'sitecopy', 'sng', 'socat', 'stow', 'stunnel', 'time', 'unison2.27', 'unison2.32', 'unison2.40', 'unison2.45', 'unison2.48']),
- 'Blooey McFooey': maintainers.Maintainer('Blooey McFooey', [], []),
+ 'Blooey McFooey': maintainers.Maintainer('Blooey McFooey', [], ['testpackage']),
'Bob Heckel': maintainers.Maintainer('Bob Heckel', [], ['libgc', 'w3m']),
'Chris J. Breisch': maintainers.Maintainer('Chris J. Breisch', [], ['man-db']),
'Chris LeBlanc': maintainers.Maintainer('Chris LeBlanc', [], ['python-h5py', 'python3-h5py']),
diff --git a/testdata/process_arch/homedir.expected b/testdata/process_arch/homedir.expected
new file mode 100644
index 0000000..39fb742
--- /dev/null
+++ b/testdata/process_arch/homedir.expected
@@ -0,0 +1,14 @@
+{'.': [],
+ 'Blooey McFooey': [],
+ 'Blooey McFooey/x86': [],
+ 'Blooey McFooey/x86/release': [],
+ 'Blooey McFooey/x86/release/after-ready': ['after-ready-1.0-1.tar.bz2', 'setup.hint'],
+ 'Blooey McFooey/x86/release/not-on-maintainer-list': ['not-on-maintainer-list-1.0-1.tar.bz2', 'setup.hint'],
+ 'Blooey McFooey/x86/release/not-on-package-list': ['not-on-package-list-1.0-1.tar.bz2', 'setup.hint'],
+ 'Blooey McFooey/x86/release/not-ready': ['-not-ready-0.9-1.tar.bz2', 'not-ready-1.0-1.tar.bz2', 'setup.hint'],
+ 'Blooey McFooey/x86/release/testpackage': [],
+ 'Blooey McFooey/x86/release/testpackage/testpackage-subpackage': [],
+ 'Blooey McFooey/x86/release/testpackage2': ['setup.hint', 'testpackage2-1.0-1.tar.bz2'],
+ 'Blooey McFooey/x86/release/testpackage2/testpackage2-subpackage': ['setup.hint',
+ 'testpackage2-subpackage-1.0-1.tar.bz2'],
+ 'Jon Turney': ['!email']}
diff --git a/testdata/process_arch/htdocs.expected b/testdata/process_arch/htdocs.expected
new file mode 100644
index 0000000..174081f
--- /dev/null
+++ b/testdata/process_arch/htdocs.expected
@@ -0,0 +1,24 @@
+{'.': [],
+ 'x86': ['.htaccess', 'packages.inc'],
+ 'x86/arc': ['.htaccess', 'arc-4.32.7-10', 'arc-4.32.7-10-src'],
+ 'x86/base-cygwin': ['.htaccess', 'base-cygwin-3.6-1', 'base-cygwin-3.8-1'],
+ 'x86/cygwin': ['.htaccess',
+ 'cygwin-2.2.0-1',
+ 'cygwin-2.2.0-1-src',
+ 'cygwin-2.2.1-1',
+ 'cygwin-2.2.1-1-src',
+ 'cygwin-2.3.0-0.3',
+ 'cygwin-2.3.0-0.3-src'],
+ 'x86/cygwin-debuginfo': ['.htaccess',
+ 'cygwin-debuginfo-2.2.0-1',
+ 'cygwin-debuginfo-2.2.1-1',
+ 'cygwin-debuginfo-2.3.0-0.3'],
+ 'x86/cygwin-devel': ['.htaccess', 'cygwin-devel-2.2.0-1', 'cygwin-devel-2.2.1-1', 'cygwin-devel-2.3.0-0.3'],
+ 'x86/keychain': ['.htaccess', 'keychain-3.1.5-1', 'keychain-3.1.5-1-src', 'keychain-3.2.0-1', 'keychain-3.2.0-1-src'],
+ 'x86/libdns_sd-devel': ['.htaccess', 'libdns_sd-devel-379.32.1-1'],
+ 'x86/libdns_sd1': ['.htaccess', 'libdns_sd1-379.32.1-1'],
+ 'x86/mDNSResponder': ['.htaccess', 'mDNSResponder-379.32.1-1', 'mDNSResponder-379.32.1-1-src'],
+ 'x86/openssh': ['.htaccess', 'openssh-7.2p2-1', 'openssh-7.2p2-1-src'],
+ 'x86/rpm-doc': ['.htaccess', 'rpm-doc-4.1-2', 'rpm-doc-4.1-2-src', 'rpm-doc-999-1'],
+ 'x86/testpackage': ['.htaccess', 'testpackage-1.0-1', 'testpackage-1.0-1-src'],
+ 'x86/testpackage-subpackage': ['.htaccess', 'testpackage-subpackage-1.0-1']}
diff --git a/testdata/process_arch/rel_area.expected b/testdata/process_arch/rel_area.expected
new file mode 100644
index 0000000..1770b4b
--- /dev/null
+++ b/testdata/process_arch/rel_area.expected
@@ -0,0 +1,57 @@
+{'.': ['setup.ini'],
+ 'x86': ['sha512.sum'],
+ 'x86/release': ['.gitignore', 'sha512.sum'],
+ 'x86/release/arc': ['arc-4.32.7-10-src.tar.bz2', 'arc-4.32.7-10.tar.bz2', 'setup.hint', 'sha512.sum'],
+ 'x86/release/base-cygwin': ['base-cygwin-3.6-1.tar.xz', 'base-cygwin-3.8-1.tar.xz', 'setup.hint', 'sha512.sum'],
+ 'x86/release/cygwin': ['cygwin-2.2.0-1-src.tar.xz',
+ 'cygwin-2.2.0-1.tar.xz',
+ 'cygwin-2.2.1-1-src.tar.xz',
+ 'cygwin-2.2.1-1.tar.xz',
+ 'cygwin-2.3.0-0.3-src.tar.xz',
+ 'cygwin-2.3.0-0.3.tar.xz',
+ 'setup.hint',
+ 'sha512.sum'],
+ 'x86/release/cygwin/cygwin-debuginfo': ['cygwin-debuginfo-2.2.0-1.tar.xz',
+ 'cygwin-debuginfo-2.2.1-1.tar.xz',
+ 'cygwin-debuginfo-2.3.0-0.3.tar.xz',
+ 'setup.hint',
+ 'sha512.sum'],
+ 'x86/release/cygwin/cygwin-devel': ['cygwin-devel-2.2.0-1.tar.xz',
+ 'cygwin-devel-2.2.1-1.tar.xz',
+ 'cygwin-devel-2.3.0-0.3.tar.xz',
+ 'setup.hint',
+ 'sha512.sum'],
+ 'x86/release/invalid': ['setup.hint', 'sha512.sum'],
+ 'x86/release/keychain': ['keychain-3.1.5-1-src.tar.xz',
+ 'keychain-3.1.5-1.tar.xz',
+ 'keychain-3.2.0-1-src.tar.xz',
+ 'keychain-3.2.0-1.tar.xz',
+ 'setup.hint',
+ 'sha512.sum'],
+ 'x86/release/libspiro': ['setup.hint', 'sha512.sum'],
+ 'x86/release/libspiro/libspiro-devel': ['setup.hint', 'sha512.sum'],
+ 'x86/release/libspiro/libspiro0': ['setup.hint', 'sha512.sum'],
+ 'x86/release/libtextcat': ['libtextcat-2.2-2-src.tar.bz2', 'libtextcat-2.2-2.tar.bz2', 'setup.hint', 'sha512.sum'],
+ 'x86/release/libtextcat/libtextcat-devel': ['libtextcat-devel-2.2-2.tar.bz2', 'setup.hint', 'sha512.sum'],
+ 'x86/release/libtextcat/libtextcat0': ['libtextcat0-2.2-2.tar.bz2', 'setup.hint', 'sha512.sum'],
+ 'x86/release/mDNSResponder': ['mDNSResponder-379.32.1-1-src.tar.bz2',
+ 'mDNSResponder-379.32.1-1.tar.bz2',
+ 'setup.hint',
+ 'sha512.sum'],
+ 'x86/release/mDNSResponder/libdns_sd-devel': ['libdns_sd-devel-379.32.1-1.tar.bz2', 'setup.hint', 'sha512.sum'],
+ 'x86/release/mDNSResponder/libdns_sd1': ['libdns_sd1-379.32.1-1.tar.bz2', 'setup.hint', 'sha512.sum'],
+ 'x86/release/mingw64-i686-binutils': ['setup.hint', 'sha512.sum'],
+ 'x86/release/mingw64-i686-binutils/mingw64-i686-binutils-debuginfo': ['setup.hint', 'sha512.sum'],
+ 'x86/release/naim': ['setup.hint'],
+ 'x86/release/openssh': ['openssh-7.2p2-1-src.tar.xz', 'openssh-7.2p2-1.tar.xz', 'setup.hint', 'sha512.sum'],
+ 'x86/release/proj': ['setup.hint', 'sha512.sum'],
+ 'x86/release/proj/libproj-devel': ['setup.hint', 'sha512.sum'],
+ 'x86/release/proj/libproj1': ['setup.hint', 'sha512.sum'],
+ 'x86/release/rpm-doc': ['rpm-doc-4.1-2-src.tar.bz2',
+ 'rpm-doc-4.1-2.tar.bz2',
+ 'rpm-doc-999-1.tar.bz2',
+ 'setup.hint',
+ 'sha512.sum'],
+ 'x86/release/splint': ['setup.hint', 'sha512.sum'],
+ 'x86/release/testpackage': ['setup.hint', 'sha512.sum', 'testpackage-1.0-1-src.tar.bz2', 'testpackage-1.0-1.tar.bz2'],
+ 'x86/release/testpackage/testpackage-subpackage': ['setup.hint', 'testpackage-subpackage-1.0-1.tar.bz2']}
diff --git a/testdata/process_arch/vault.expected b/testdata/process_arch/vault.expected
new file mode 100644
index 0000000..a87938b
--- /dev/null
+++ b/testdata/process_arch/vault.expected
@@ -0,0 +1 @@
+{'.': [], 'x86': [], 'x86/release': [], 'x86/release/testpackage': ['testpackage-0.1-1.tar.bz2']}
diff --git a/testdata/uploads/move.expected b/testdata/uploads/move.expected
index 4353d4f..b0caaf3 100644
--- a/testdata/uploads/move.expected
+++ b/testdata/uploads/move.expected
@@ -1,3 +1,3 @@
-{'release/testpackage': ['setup.hint', 'testpackage-1.0-1.tar.bz2'],
+{'release/testpackage': ['setup.hint', 'testpackage-1.0-1-src.tar.bz2', 'testpackage-1.0-1.tar.bz2'],
'release/testpackage/testpackage-subpackage': ['setup.hint', 'testpackage-subpackage-1.0-1.tar.bz2'],
'release/testpackage2/testpackage2-subpackage': ['setup.hint', 'testpackage2-subpackage-1.0-1.tar.bz2']}
diff --git a/testdata/uploads/pkglist.expected b/testdata/uploads/pkglist.expected
index 3ab6f49..8caa9aa 100644
--- a/testdata/uploads/pkglist.expected
+++ b/testdata/uploads/pkglist.expected
@@ -1,9 +1,11 @@
-{'testpackage': Package('release/testpackage', {'testpackage-1.0-1.tar.bz2': Tar('aff488008bee3486e25b539fe6ccd1397bd3c5c0ba2ee2cf34af279554baa195af7493ee51d6f8510735c9a2ea54436d776a71e768165716762aec286abbbf83', 195, False)}, {'sdesc': '"A test package"',
+{'testpackage': Package('release/testpackage', {'testpackage-1.0-1-src.tar.bz2': Tar('aff488008bee3486e25b539fe6ccd1397bd3c5c0ba2ee2cf34af279554baa195af7493ee51d6f8510735c9a2ea54436d776a71e768165716762aec286abbbf83', 195, False),
+ 'testpackage-1.0-1.tar.bz2': Tar('aff488008bee3486e25b539fe6ccd1397bd3c5c0ba2ee2cf34af279554baa195af7493ee51d6f8510735c9a2ea54436d776a71e768165716762aec286abbbf83', 195, False)}, {'sdesc': '"A test package"',
'ldesc': '"A test package"',
'category': 'Devel'}),
'testpackage-subpackage': Package('release/testpackage/testpackage-subpackage', {'testpackage-subpackage-1.0-1.tar.bz2': Tar('aff488008bee3486e25b539fe6ccd1397bd3c5c0ba2ee2cf34af279554baa195af7493ee51d6f8510735c9a2ea54436d776a71e768165716762aec286abbbf83', 195, False)}, {'sdesc': '"A test subpackage"',
'ldesc': '"A test subpackage"',
- 'category': 'Devel'}),
+ 'category': 'Devel',
+ 'external-source': 'testpackage'}),
'testpackage2-subpackage': Package('release/testpackage2/testpackage2-subpackage', {'testpackage2-subpackage-1.0-1.tar.bz2': Tar('aff488008bee3486e25b539fe6ccd1397bd3c5c0ba2ee2cf34af279554baa195af7493ee51d6f8510735c9a2ea54436d776a71e768165716762aec286abbbf83', 195, False)}, {'sdesc': '"A test subpackage 2"',
'ldesc': '"A test subpackage 2"',
'category': 'Devel'})}
diff --git a/testdata/x86.hints/release/libtextcat/libtextcat-devel/expected b/testdata/x86.hints/release/libtextcat/libtextcat-devel/expected
index f79513f..f60d34d 100644
--- a/testdata/x86.hints/release/libtextcat/libtextcat-devel/expected
+++ b/testdata/x86.hints/release/libtextcat/libtextcat-devel/expected
@@ -1,4 +1,12 @@
{'sdesc': '"Helper, header and library for libtextcat"',
+ 'ldesc': '"Libtextcat is a library with functions that implement the\n'
+ 'classification technique described in Cavnar & Trenkle, "N-Gram-Based\n'
+ 'Text Categorization". It was primarily developed for language\n'
+ 'guessing, a task on which it is known to perform with near-perfect\n'
+ 'accuracy.\n'
+ 'BSD License.\n'
+ 'http://software.wise-guys.nl/libtextcat/"',
'category': 'Devel Text',
'requires': 'libtextcat0 libtextcat',
- 'external-source': 'libtextcat'}
+ 'external-source': 'libtextcat',
+ 'parse-errors': ['embedded quote at line 7']}
diff --git a/testdata/x86.hints/release/libtextcat/libtextcat0/expected b/testdata/x86.hints/release/libtextcat/libtextcat0/expected
index 45bcd21..7f186d6 100644
--- a/testdata/x86.hints/release/libtextcat/libtextcat0/expected
+++ b/testdata/x86.hints/release/libtextcat/libtextcat0/expected
@@ -1,4 +1,12 @@
{'sdesc': '"Text Classification Library dll"',
+ 'ldesc': '"Libtextcat is a library with functions that implement the\n'
+ 'classification technique described in Cavnar & Trenkle, "N-Gram-Based\n'
+ 'Text Categorization". It was primarily developed for language\n'
+ 'guessing, a task on which it is known to perform with near-perfect\n'
+ 'accuracy.\n'
+ 'BSD License.\n'
+ 'http://software.wise-guys.nl/libtextcat/"',
'category': 'Text',
'requires': 'cygwin',
- 'external-source': 'libtextcat'}
+ 'external-source': 'libtextcat',
+ 'parse-errors': ['embedded quote at line 7']}
diff --git a/testdata/x86.hints/release/naim/expected b/testdata/x86.hints/release/naim/expected
index 8519f73..9f7710c 100644
--- a/testdata/x86.hints/release/naim/expected
+++ b/testdata/x86.hints/release/naim/expected
@@ -1,5 +1,5 @@
{'category': 'Net',
- 'requires': 'libgcc1 libncursesw10',
+ 'requires': '',
'sdesc': '"Console AIM, ICQ, IRC, and Lily client"',
'ldesc': '" naim is a console client for AOL Instant Messenger (AIM),\n'
'AOL I Seek You (ICQ), Internet Relay Chat (IRC), and The lily CMC."',
diff --git a/testdata/x86.hints/release/openssh/expected b/testdata/x86.hints/release/openssh/expected
new file mode 100644
index 0000000..8eeefad
--- /dev/null
+++ b/testdata/x86.hints/release/openssh/expected
@@ -0,0 +1,5 @@
+{'category': 'Net',
+ 'sdesc': '"The OpenSSH server and client programs"',
+ 'ldesc': '"OpenSSH is a program for logging into a remote machine and for\n'
+ '\texecuting commands on a remote machine. It can replace rlogin and rsh,\n'
+ '\tproviding encrypted communication between two machines."'}
diff --git a/testdata/x86/release/libtextcat/libtextcat-devel/setup.hint b/testdata/x86/release/libtextcat/libtextcat-devel/setup.hint
index 5c07d50..f509126 100644
--- a/testdata/x86/release/libtextcat/libtextcat-devel/setup.hint
+++ b/testdata/x86/release/libtextcat/libtextcat-devel/setup.hint
@@ -1,4 +1,11 @@
sdesc: "Helper, header and library for libtextcat"
+ldesc: "Libtextcat is a library with functions that implement the
+classification technique described in Cavnar & Trenkle, "N-Gram-Based
+Text Categorization". It was primarily developed for language
+guessing, a task on which it is known to perform with near-perfect
+accuracy.
+BSD License.
+http://software.wise-guys.nl/libtextcat/"
category: Devel Text
requires: libtextcat0 libtextcat
external-source: libtextcat
diff --git a/testdata/x86/release/libtextcat/libtextcat0/setup.hint b/testdata/x86/release/libtextcat/libtextcat0/setup.hint
index d1475a7..f3ae673 100644
--- a/testdata/x86/release/libtextcat/libtextcat0/setup.hint
+++ b/testdata/x86/release/libtextcat/libtextcat0/setup.hint
@@ -1,4 +1,11 @@
sdesc: "Text Classification Library dll"
+ldesc: "Libtextcat is a library with functions that implement the
+classification technique described in Cavnar & Trenkle, "N-Gram-Based
+Text Categorization". It was primarily developed for language
+guessing, a task on which it is known to perform with near-perfect
+accuracy.
+BSD License.
+http://software.wise-guys.nl/libtextcat/"
category: Text
requires: cygwin
external-source: libtextcat
diff --git a/testdata/x86/release/naim/setup.hint b/testdata/x86/release/naim/setup.hint
index d24a6ce..7de6e7b 100644
--- a/testdata/x86/release/naim/setup.hint
+++ b/testdata/x86/release/naim/setup.hint
@@ -1,5 +1,5 @@
category: Net
-requires: libgcc1 libncursesw10
+requires:
sdesc: "Console AIM, ICQ, IRC, and Lily client"
ldesc: " naim is a console client for AOL Instant Messenger (AIM),
AOL I Seek You (ICQ), Internet Relay Chat (IRC), and The lily CMC."
diff --git a/testdata/x86/release/openssh/openssh-7.2p2-1-src.tar.xz b/testdata/x86/release/openssh/openssh-7.2p2-1-src.tar.xz
new file mode 100644
index 0000000..0e6f1e8
Binary files /dev/null and b/testdata/x86/release/openssh/openssh-7.2p2-1-src.tar.xz differ
diff --git a/testdata/x86/release/openssh/openssh-7.2p2-1.tar.xz b/testdata/x86/release/openssh/openssh-7.2p2-1.tar.xz
new file mode 100644
index 0000000..0e6f1e8
Binary files /dev/null and b/testdata/x86/release/openssh/openssh-7.2p2-1.tar.xz differ
diff --git a/testdata/x86/release/openssh/setup.hint b/testdata/x86/release/openssh/setup.hint
new file mode 100644
index 0000000..83aa11a
--- /dev/null
+++ b/testdata/x86/release/openssh/setup.hint
@@ -0,0 +1,5 @@
+category: Net
+sdesc: "The OpenSSH server and client programs"
+ldesc: "OpenSSH is a program for logging into a remote machine and for
+ executing commands on a remote machine. It can replace rlogin and rsh,
+ providing encrypted communication between two machines."
diff --git a/testdata/x86/release/proj/proj-debuginfo/proj-debuginfo-4.8.0-1.tar.xz b/testdata/x86/release/proj/proj-debuginfo/proj-debuginfo-4.8.0-1.tar.xz
deleted file mode 100644
index a1145fb..0000000
Binary files a/testdata/x86/release/proj/proj-debuginfo/proj-debuginfo-4.8.0-1.tar.xz and /dev/null differ
diff --git a/testdata/x86/release/proj/proj-debuginfo/setup.hint b/testdata/x86/release/proj/proj-debuginfo/setup.hint
deleted file mode 100644
index ac6fb1e..0000000
--- a/testdata/x86/release/proj/proj-debuginfo/setup.hint
+++ /dev/null
@@ -1,6 +0,0 @@
-category: Debug
-requires: cygwin-debuginfo
-external-source: proj
-sdesc: "Debug info for proj"
-ldesc: "This package contains files necessary for debugging the
-proj package with gdb."
diff --git a/testdata/x86/release/rpm-doc/rpm-doc-4.1-2-src.tar.bz2 b/testdata/x86/release/rpm-doc/rpm-doc-4.1-2-src.tar.bz2
new file mode 100644
index 0000000..cbf838c
Binary files /dev/null and b/testdata/x86/release/rpm-doc/rpm-doc-4.1-2-src.tar.bz2 differ
diff --git a/testdata/x86/release/testpackage/testpackage-0.1-1.tar.bz2 b/testdata/x86/release/testpackage/testpackage-0.1-1.tar.bz2
new file mode 100644
index 0000000..e69de29
diff --git a/tests.py b/tests.py
index 5b97297..6f0ff19 100755
--- a/tests.py
+++ b/tests.py
@@ -30,10 +30,13 @@ import logging
import os
import pprint
import re
+import shutil
+import tempfile
import types
import unittest
from version import SetupVersion
+import calm
import hint
import maintainers
import package
@@ -42,7 +45,7 @@ import uploads
#
-# helper function
+# helper functions
#
# write results to the file 'results'
# read expected from the file 'expected'
@@ -71,6 +74,19 @@ def compare_with_expected_file(test, dirpath, results, basename=None):
#
+# capture a directory tree as a dict 'tree', where each key is a directory path
+# and the value is a sorted list of filenames
+#
+
+def capture_dirtree(basedir):
+ tree = {}
+ for dirpath, dirnames, filenames in os.walk(basedir):
+ tree[os.path.relpath(dirpath, basedir)] = sorted(filenames)
+
+ return tree
+
+
+#
#
#
@@ -189,7 +205,7 @@ class TestMain(unittest.TestCase):
self.assertEqual(error, False)
compare_with_expected_file(self, 'testdata/uploads', to_relarea, 'move')
self.assertCountEqual(remove_always, [f for (f, t) in ready_fns])
- self.assertEqual(remove_success, [])
+ self.assertEqual(remove_success, ['testdata/homes/Blooey McFooey/x86/release/testpackage/-testpackage-0.1-1.tar.bz2'])
compare_with_expected_file(self, 'testdata/uploads', packages, 'pkglist')
def test_package_set(self):
@@ -207,10 +223,7 @@ class TestMain(unittest.TestCase):
packages = package.read_packages(args.rel_area, args.arch)
package.delete(packages, 'release/nonexistent', 'nosuchfile-1.0.0.tar.xz')
- package.delete(packages, 'release/libtextcat/libtextcat-devel', 'libtextcat-devel-2.2-2.tar.bz2')
- package.delete(packages, 'release/libtextcat/libtextcat0', 'libtextcat0-2.2-2.tar.bz2')
- package.delete(packages, 'release/proj/proj-debuginfo', 'proj-debuginfo-4.8.0-1.tar.xz')
- package.validate_packages(args, packages)
+ self.assertEqual(package.validate_packages(args, packages), True)
package.write_setup_ini(args, packages)
with open(args.inifile) as inifile:
results = inifile.read()
@@ -218,6 +231,45 @@ class TestMain(unittest.TestCase):
results = re.sub('setup-timestamp: .*', 'setup-timestamp: 1458221800', results, 1)
compare_with_expected_file(self, 'testdata/inifile', (results,), 'setup.ini')
+ # XXX: delete a needed package, and check validate fails
+
+ def test_process_arch(self):
+ self.maxDiff = None
+
+ args = types.SimpleNamespace()
+
+ for d in ['rel_area', 'homedir', 'htdocs', 'vault']:
+ setattr(args, d, tempfile.mktemp())
+ logging.info('%s = %s', d, getattr(args, d))
+
+ setattr(args, 'arch', 'x86')
+ setattr(args, 'dryrun', False)
+ setattr(args, 'email', None)
+ setattr(args, 'force', False)
+ setattr(args, 'inifile', os.path.join(getattr(args, 'rel_area'), 'setup.ini'))
+ setattr(args, 'pkglist', 'testdata/pkglist/cygwin-pkg-maint')
+ setattr(args, 'release', 'trial')
+ setattr(args, 'setup_version', '3.1415')
+
+ shutil.copytree('testdata/x86', os.path.join(getattr(args, 'rel_area'), 'x86'))
+ shutil.copytree('testdata/homes', getattr(args, 'homedir'))
+
+ # set appropriate !readys
+ m_homedir = os.path.join(getattr(args, 'homedir'), 'Blooey McFooey')
+ ready_fns = [(os.path.join(m_homedir, 'x86', 'release', 'testpackage', '!ready'), ''),
+ (os.path.join(m_homedir, 'x86', 'release', 'testpackage2', 'testpackage2-subpackage', '!ready'), ''),
+ (os.path.join(m_homedir, 'x86', 'release', 'after-ready', '!ready'), '-t 198709011700')]
+ for (f, t) in ready_fns:
+ os.system('touch %s "%s"' % (t, f))
+
+ self.assertEqual(calm.main(args), 0)
+
+ for d in ['rel_area', 'homedir', 'htdocs', 'vault']:
+ with self.subTest(directory=d):
+ dirlist = capture_dirtree(getattr(args, d))
+ compare_with_expected_file(self, 'testdata/process_arch', dirlist, d)
+ shutil.rmtree(getattr(args, d))
+
if __name__ == '__main__':
# ensure sha512.sum files exist
os.system("find testdata/x86 -type d -exec sh -c 'cd {} ; sha512sum * >sha512.sum 2>/dev/null' \;")
diff --git a/uploads.py b/uploads.py
index 33ae511..050c494 100644
--- a/uploads.py
+++ b/uploads.py
@@ -171,16 +171,17 @@ def remove(args, remove):
#
def move(args, movelist, fromdir, todir):
- for p in movelist:
+ for p in sorted(movelist):
logging.info("mkdir %s" % os.path.join(todir, p))
if not args.dryrun:
try:
os.makedirs(os.path.join(todir, p), exist_ok=True)
except FileExistsError:
pass
- for f in movelist[p]:
+ logging.warning("move from '%s' to '%s':" % (os.path.join(fromdir, p), os.path.join(todir, p)))
+ for f in sorted(movelist[p]):
if os.path.exists(os.path.join(fromdir, p, f)):
- logging.warning("move %s to %s" % (os.path.join(fromdir, p, f), os.path.join(todir, p, f)))
+ logging.warning("%s" % (f))
if not args.dryrun:
os.rename(os.path.join(fromdir, p, f), os.path.join(todir, p, f))
else:
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2016-03-21 12:31 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-21 12:31 [calm - Cygwin server-side packaging maintenance script] branch master, updated. df7ae0d55a584fdd03ed01f3f073e8d4e0abf826 jturney
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).