parameters: (args)
return_statement: return 0
docstring: A Unix style zip.
  
    Compresses the listed files.
docstring_summary: A Unix style zip.
docstring_tokens: A Unix style zip .
function: def Zip(args):
    """A Unix style zip.
  
    Compresses the listed files."""
    parser = optparse.OptionParser(usage='usage: zip [Options] zipfile list')
    parser.add_option(
        '-r', dest='recursive', action='store_true',
        default=False,
        help='recurse into directories')
    parser.add_option(
        '-q', dest='quiet', action='store_true',
        default=False,
        help='quiet operation')
    options, files = parser.parse_args(args)
    if len(files) < 2:
      parser.error('ERROR: expecting ZIPFILE and LIST.')
  
    dest_zip = files[0]
    src_args = files[1:]
  
    src_files = []
    for src_arg in src_args:
      globbed_src_args = glob.glob(src_arg)
      if not globbed_src_args:
        if not options.quiet:
          print 'zip warning: name not matched: %s' % (src_arg,)
  
      for src_file in globbed_src_args:
        src_file = os.path.normpath(src_file)
        src_files.append(src_file)
        if options.recursive and os.path.isdir(src_file):
          for root, dirs, files in os.walk(src_file):
            for dirname in dirs:
              src_files.append(os.path.join(root, dirname))
            for filename in files:
              src_files.append(os.path.join(root, filename))
  
    zip_stream = None
    # zip_data represents a list of the data to be written or appended to the
    # zip_stream. It is a list of tuples:
    #   (OS file path, zip path/zip file info, and file data)
    # In all cases one of the |os path| or the |file data| will be None.
    # |os path| is None when there is no OS file to write to the archive (i.e.
    # the file data already existed in the archive). |file data| is None when the
    # file is new (never existed in the archive) or being updated.
    zip_data = []
    new_files_to_add = [OSMakeZipPath(src_file) for src_file in src_files]
    zip_path_to_os_path_dict = dict((new_files_to_add[i], src_files[i])
                                    for i in range(len(src_files)))
    write_mode = 'a'
    try:
      zip_stream = zipfile.ZipFile(dest_zip, 'r')
      files_to_update = set(new_files_to_add).intersection(
          set(zip_stream.namelist()))
      if files_to_update:
        # As far as I can tell, there is no way to update a zip entry using
        # zipfile; the best you can do is rewrite the archive.
        # Iterate through the zipfile to maintain file order.
        write_mode = 'w'
        for zip_path in zip_stream.namelist():
          if zip_path in files_to_update:
            os_path = zip_path_to_os_path_dict[zip_path]
            zip_data.append((os_path, zip_path, None))
            new_files_to_add.remove(zip_path)
          else:
            file_bytes = zip_stream.read(zip_path)
            file_info = zip_stream.getinfo(zip_path)
            zip_data.append((None, file_info, file_bytes))
    except IOError:
      pass
    finally:
      if zip_stream:
        zip_stream.close()
  
    for zip_path in new_files_to_add:
      zip_data.append((zip_path_to_os_path_dict[zip_path], zip_path, None))
  
    if not zip_data:
      print 'zip error: Nothing to do! (%s)' % (dest_zip,)
      return 1
  
    try:
      zip_stream = zipfile.ZipFile(dest_zip, write_mode, zipfile.ZIP_DEFLATED)
      for os_path, file_info_or_zip_path, file_bytes in zip_data:
        if isinstance(file_info_or_zip_path, zipfile.ZipInfo):
          zip_path = file_info_or_zip_path.filename
        else:
          zip_path = file_info_or_zip_path
  
        if os_path:
          st = os.stat(os_path)
          if stat.S_ISDIR(st.st_mode):
            # Python 2.6 on the buildbots doesn't support writing directories to
            # zip files. This was resolved in a later version of Python 2.6.
            # We'll work around it by writing an empty file with the correct
            # path. (This is basically what later versions do anyway.)
            zip_info = zipfile.ZipInfo()
            zip_info.filename = zip_path
            zip_info.date_time = time.localtime(st.st_mtime)[0:6]
            zip_info.compress_type = zip_stream.compression
            zip_info.flag_bits = 0x00
            zip_info.external_attr = (st[0] & 0xFFFF) << 16L
            zip_info.CRC = 0
            zip_info.compress_size = 0
            zip_info.file_size = 0
            zip_stream.writestr(zip_info, '')
          else:
            zip_stream.write(os_path, zip_path)
        else:
          zip_stream.writestr(file_info_or_zip_path, file_bytes)
  
        if not options.quiet:
          if zip_path in new_files_to_add:
            operation = 'adding'
          else:
            operation = 'updating'
          zip_info = zip_stream.getinfo(zip_path)
          if (zip_info.compress_type == zipfile.ZIP_STORED or
              zip_info.file_size == 0):
            print '  %s: %s (stored 0%%)' % (operation, zip_path)
          elif zip_info.compress_type == zipfile.ZIP_DEFLATED:
            print '  %s: %s (deflated %d%%)' % (operation, zip_path,
                100 - zip_info.compress_size * 100 / zip_info.file_size)
    finally:
      zip_stream.close()
  
    return 0
function_tokens: def Zip ( args ) : parser = optparse . OptionParser ( usage = 'usage: zip [Options] zipfile list' ) parser . add_option ( '-r' , dest = 'recursive' , action = 'store_true' , default = False , help = 'recurse into directories' ) parser . add_option ( '-q' , dest = 'quiet' , action = 'store_true' , default = False , help = 'quiet operation' ) options , files = parser . parse_args ( args ) if len ( files ) < 2 : parser . error ( 'ERROR: expecting ZIPFILE and LIST.' ) dest_zip = files [ 0 ] src_args = files [ 1 : ] src_files = [ ] for src_arg in src_args : globbed_src_args = glob . glob ( src_arg ) if not globbed_src_args : if not options . quiet : print 'zip warning: name not matched: %s' % ( src_arg , ) for src_file in globbed_src_args : src_file = os . path . normpath ( src_file ) src_files . append ( src_file ) if options . recursive and os . path . isdir ( src_file ) : for root , dirs , files in os . walk ( src_file ) : for dirname in dirs : src_files . append ( os . path . join ( root , dirname ) ) for filename in files : src_files . append ( os . path . join ( root , filename ) ) zip_stream = None # zip_data represents a list of the data to be written or appended to the # zip_stream. It is a list of tuples: #   (OS file path, zip path/zip file info, and file data) # In all cases one of the |os path| or the |file data| will be None. # |os path| is None when there is no OS file to write to the archive (i.e. # the file data already existed in the archive). |file data| is None when the # file is new (never existed in the archive) or being updated. zip_data = [ ] new_files_to_add = [ OSMakeZipPath ( src_file ) for src_file in src_files ] zip_path_to_os_path_dict = dict ( ( new_files_to_add [ i ] , src_files [ i ] ) for i in range ( len ( src_files ) ) ) write_mode = 'a' try : zip_stream = zipfile . ZipFile ( dest_zip , 'r' ) files_to_update = set ( new_files_to_add ) . intersection ( set ( zip_stream . namelist ( ) ) ) if files_to_update : # As far as I can tell, there is no way to update a zip entry using # zipfile; the best you can do is rewrite the archive. # Iterate through the zipfile to maintain file order. write_mode = 'w' for zip_path in zip_stream . namelist ( ) : if zip_path in files_to_update : os_path = zip_path_to_os_path_dict [ zip_path ] zip_data . append ( ( os_path , zip_path , None ) ) new_files_to_add . remove ( zip_path ) else : file_bytes = zip_stream . read ( zip_path ) file_info = zip_stream . getinfo ( zip_path ) zip_data . append ( ( None , file_info , file_bytes ) ) except IOError : pass finally : if zip_stream : zip_stream . close ( ) for zip_path in new_files_to_add : zip_data . append ( ( zip_path_to_os_path_dict [ zip_path ] , zip_path , None ) ) if not zip_data : print 'zip error: Nothing to do! (%s)' % ( dest_zip , ) return 1 try : zip_stream = zipfile . ZipFile ( dest_zip , write_mode , zipfile . ZIP_DEFLATED ) for os_path , file_info_or_zip_path , file_bytes in zip_data : if isinstance ( file_info_or_zip_path , zipfile . ZipInfo ) : zip_path = file_info_or_zip_path . filename else : zip_path = file_info_or_zip_path if os_path : st = os . stat ( os_path ) if stat . S_ISDIR ( st . st_mode ) : # Python 2.6 on the buildbots doesn't support writing directories to # zip files. This was resolved in a later version of Python 2.6. # We'll work around it by writing an empty file with the correct # path. (This is basically what later versions do anyway.) zip_info = zipfile . ZipInfo ( ) zip_info . filename = zip_path zip_info . date_time = time . localtime ( st . st_mtime ) [ 0 : 6 ] zip_info . compress_type = zip_stream . compression zip_info . flag_bits = 0x00 zip_info . external_attr = ( st [ 0 ] & 0xFFFF ) << 16L zip_info . CRC = 0 zip_info . compress_size = 0 zip_info . file_size = 0 zip_stream . writestr ( zip_info , '' ) else : zip_stream . write ( os_path , zip_path ) else : zip_stream . writestr ( file_info_or_zip_path , file_bytes ) if not options . quiet : if zip_path in new_files_to_add : operation = 'adding' else : operation = 'updating' zip_info = zip_stream . getinfo ( zip_path ) if ( zip_info . compress_type == zipfile . ZIP_STORED or zip_info . file_size == 0 ) : print '  %s: %s (stored 0%%)' % ( operation , zip_path ) elif zip_info . compress_type == zipfile . ZIP_DEFLATED : print '  %s: %s (deflated %d%%)' % ( operation , zip_path , 100 - zip_info . compress_size * 100 / zip_info . file_size ) finally : zip_stream . close ( ) return 0