Richard Jones' Log: Distutils MANIFEST checking

Fri, 16 Apr 2004

So it turns out that some programs don't unpack distutils tarballs correctly. My test runner now executes the following code:

def check_manifest():
    """Check that the files listed in the MANIFEST are present when the
    source is unpacked.
    """
    try:
        f = open('MANIFEST')
    except:
        print '\n*** SOURCE ERROR: The MANIFEST file is missing!'
        sys.exit(1)
    try:
        manifest = [l.strip() for l in f.readlines()]
    finally:
        f.close()
    err = [line for line in manifest if not os.path.exists(line)]
    if err:
        n = len(manifest)
        print '\n*** SOURCE ERROR: There are files missing (%d/%d found)!'%(
            n-len(err), n)
        sys.exit(1)

Distutils doesn't automatically check the files unpacked from a source distribution against the packaged MANIFEST. I'm not sure that it could, without potentially breaking some of the other distribution mechanisms. This uncertainty comes from having no clue as to how I could make it run this function when someone tries to install Roundup from source... Anyone? :)

Update: I believe the following is safe. Instead of checking the manifest at install time, I check it at build time:

from distutils.command.build import build

class build_roundup(build):
    def run(self):
        check_manifest()
        build.run(self)

later:

setup(
    ...
    cmdclass = {
        'build': build_roundup,
    },
)
Comment by Fredrik Lundh on Fri, 16 Apr 2004

There's a checkbox in WinZIP that allows you to unpack everything into a single directory. In my experience, when people get "errors" from WinZIP (which are warnings that they're overwriting files) and files are missing, they've always messed around with that option.

Adding "If you're using WinZIP's 'classic' interface, make sure the 'Use folder names' check box is checked before you extract the files." to the instructions might help.

As for the sanity check itself, why not add it to the setup.py file?

Cheers /F

Comment by Richard on Fri, 16 Apr 2004

Oh, I want to run it in the setup file (it's defined in there). My concern is that it can't be run for every kind of setup.py invocation - hence I need to figure how to hook it into invocations of the "install" command. And make sure that things like RPM packaging and windows installer thingies don't break.

Comment by Richard on Fri, 16 Apr 2004

(and I've added a note to the install regarding WinZIP's classic more, thanks!)