userland-mangler revision 1113
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#!/usr/bin/python2.6
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# CDDL HEADER START
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# The contents of this file are subject to the terms of the
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# Common Development and Distribution License (the "License").
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# You may not use this file except in compliance with the License.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# or http://www.opensolaris.org/os/licensing.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# See the License for the specific language governing permissions
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# and limitations under the License.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# When distributing Covered Code, include this CDDL HEADER in each
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# If applicable, add the following below this CDDL HEADER, with the
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# fields enclosed by brackets "[]" replaced with your own identifying
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# information: Portions Copyright [yyyy] [name of copyright owner]
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# CDDL HEADER END
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# userland-mangler - a file mangling utility
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# A simple program to mangle files to conform to Solaris WOS or Consoldation
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# requirements.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweimport os
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweimport sys
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweimport re
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweimport pkg.fmri
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweimport pkg.manifest
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweimport pkg.actions
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweimport pkg.elf as elf
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweattribute_oracle_table_header = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.\\\" Oracle has added the ARC stability level to this manual page"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweattribute_table_header = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.SH ATTRIBUTES
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweSee
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.BR attributes (5)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowefor descriptions of the following attributes:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.sp
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.TS
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowebox;
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowecbp-1 | cbp-1
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowel | l .
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweATTRIBUTE TYPE ATTRIBUTE VALUE """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweattribute_table_availability = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe=
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweAvailability %s"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweattribute_table_stability = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe=
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweStability %s"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweattribute_table_footer = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.TE
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.PP
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef attributes_section_text(availability, stability, modified_date):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result = ''
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # is there anything to do?
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if availability is not None or stability is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result = attribute_oracle_table_header
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if modified_date is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += ("\n.\\\" on %s" % modified_date)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += attribute_table_header
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if availability is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += (attribute_table_availability % availability)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if stability is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += (attribute_table_stability % stability.capitalize())
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += attribute_table_footer
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return result
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowenotes_oracle_comment = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.\\\" Oracle has added source availability information to this manual page"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowenotes_header = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe.SH NOTES
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowenotes_community = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweFurther information about this software can be found on the open source community website at %s.
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowenotes_source = """
c10c16dec587a0662068f6e2991c29ed3a9db943Richard LoweThis software was built from source available at http://opensolaris.org/. The original community source was downloaded from %s
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe"""
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef notes_section_text(header_seen, community, source, modified_date):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result = ''
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # is there anything to do?
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if community is not None or source is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if header_seen == False:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += notes_header
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += notes_oracle_comment
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if modified_date is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += ("\n.\\\" on %s" % modified_date)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if source is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += (notes_source % source)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if community is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += (notes_community % community)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return result
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Loweso_re = re.compile('^\.so.+$', re.MULTILINE)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowesection_re = re.compile('\.SH "?([^"]+).*$', re.IGNORECASE)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.man.stability = (mangler.man.stability)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.man.modified_date = (mangler.man.modified-date)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.man.availability = (pkg.fmri)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.man.source-url = (pkg.source-url)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.man.upstream-url = (pkg.upstream-url)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef mangle_manpage(manifest, action, text):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # manpages must have a taxonomy defined
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe stability = action.attrs.pop('mangler.man.stability', None)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if stability is None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe sys.stderr.write("ERROR: manpage action missing mangler.man.stability: %s" % action)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe sys.exit(1)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # manpages may have a 'modified date'
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe modified_date = action.attrs.pop('mangler.man.modified-date', None)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe attributes_written = False
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe notes_seen = False
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if 'pkg.fmri' in manifest.attributes:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe fmri = pkg.fmri.PkgFmri(manifest.attributes['pkg.fmri'])
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe availability = fmri.pkg_name
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe community = None
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if 'info.upstream-url' in manifest.attributes:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe community = manifest.attributes['info.upstream-url']
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe source = None
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if 'info.source-url' in manifest.attributes:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe source = manifest.attributes['info.source-url']
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe elif 'info.repository-url' in manifest.attributes:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe source = manifest.attributes['info.repository-url']
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # skip reference only pages
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if so_re.match(text) is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return text
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # tell man that we want tables (and eqn)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result = "'\\\" te\n"
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # write the orginal data
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe for line in text.split('\n'):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe match = section_re.match(line)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if match is not None:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe section = match.group(1)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if section in ['SEE ALSO', 'NOTES']:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if attributes_written == False:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += attributes_section_text(
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe availability,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe stability,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe modified_date)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe attributes_written = True
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if section == 'NOTES':
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe notes_seen = True
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += ("%s\n" % line)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if attributes_written == False:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += attributes_section_text(availability, stability,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe modified_date)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result += notes_section_text(notes_seen, community, source,
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe modified_date)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return result
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.elf.strip = (true|false)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef mangle_elf(manifest, action, src, dest):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe pass
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.script.file-magic =
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef mangle_script(manifest, action, text):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return text
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.strip_cddl = false
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef mangle_cddl(manifest, action, text):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe strip_cddl = action.attrs.pop('mangler.strip_cddl', 'true')
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if strip_cddl is 'false':
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return text
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe cddl_re = re.compile('^[^\n]*CDDL HEADER START.+CDDL HEADER END[^\n]*$',
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe re.MULTILINE|re.DOTALL)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe return cddl_re.sub('', text)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef mangle_path(manifest, action, src, dest):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if elf.is_elf_object(src):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe mangle_elf(manifest, action, src, dest)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe else:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # a 'text' document (script, man page, config file, ...
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe ifp = open(src, 'r')
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe text = ifp.read()
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe ifp.close()
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe # remove the CDDL from files
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result = mangle_cddl(manifest, action, text)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if 'facet.doc.man' in action.attrs:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result = mangle_manpage(manifest, action, result)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe elif 'mode' in action.attrs and int(action.attrs['mode'], 8) & 0111 != 0:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe result = mangle_script(manifest, action, result)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if text != result:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe destdir = os.path.dirname(dest)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe if not os.path.exists(destdir):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe os.makedirs(destdir)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe with open(dest, 'w') as ofp:
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe ofp.write(result)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe# mangler.bypass = (true|false)
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe#
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowedef mangle_paths(manifest, search_paths, destination):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe for action in manifest.gen_actions_by_type("file"):
c10c16dec587a0662068f6e2991c29ed3a9db943Richard Lowe bypass = action.attrs.pop('mangler.bypass', 'false').lower()
if bypass == 'true':
continue
path = None
if 'path' in action.attrs:
path = action.attrs['path']
if action.hash and action.hash != 'NOHASH':
path = action.hash
if not path:
continue
if not os.path.exists(destination):
os.makedirs(destination)
dest = os.path.join(destination, path)
for directory in search_paths:
if directory != destination:
src = os.path.join(directory, path)
if os.path.isfile(src):
mangle_path(manifest, action, src, dest)
break
def load_manifest(manifest_file):
manifest = pkg.manifest.Manifest()
manifest.set_content(pathname=manifest_file)
return manifest
def usage():
print "Usage: %s [-m|--manifest (file)] [-d|--search-directory (dir)] [-D|--destination (dir)] " % (sys.argv[0].split('/')[-1])
sys.exit(1)
def main():
import getopt
# FLUSH STDOUT
sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
search_paths = []
destination = None
manifests = []
try:
opts, args = getopt.getopt(sys.argv[1:], "D:d:m:",
["destination=", "search-directory=", "manifest="])
except getopt.GetoptError, err:
print str(err)
usage()
for opt, arg in opts:
if opt in [ "-D", "--destination" ]:
destination = arg
elif opt in [ "-d", "--search-directory" ]:
search_paths.append(arg)
elif opt in [ "-m", "--manifest" ]:
try:
manifest = load_manifest(arg)
except IOError, err:
print "oops, %s: %s" % (arg, str(err))
usage()
else:
manifests.append(manifest)
else:
usage()
if destination == None:
usage()
for manifest in manifests:
mangle_paths(manifest, search_paths, destination)
print manifest
sys.exit(0)
if __name__ == "__main__":
main()