Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  split_zips.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

package main

import (
 "bytes"
 "flag"
 "fmt"
 "log"
 "os"
 "path/filepath"
 "strings"

 "android/soong/response"
 "android/soong/third_party/zip"
 "github.com/google/blueprint/pathtools"
)

var (
 rspFile = flag.String("i", "", "RSP file containing a whitespace-separated list of input ZIPs")
 filter  multiFlag
)

func init() {
 flag.Var(&filter, "f", "optional filter pattern")
}

type zipReader struct {
 reader  *zip.Reader
 zipPath string
}

type zipWriter struct {
 writer     *zip.Writer
 zipBytes   *bytes.Buffer
 outputPath string
}

func main() {
 flag.Usage = func() {
  fmt.Fprintln(os.Stderr, "usage: split_zips -i input.rsp -f \"glob\" output1.zip [output2.zip ...]")
  flag.PrintDefaults()
  fmt.Fprintln(os.Stderr, "")
  fmt.Fprintln(os.Stderr, "Splits the combined content of input zips (from RSP file) into the specified output zip files.")
  fmt.Fprintln(os.Stderr, "<-f> uses the rules at https://godoc.org/github.com/google/blueprint/pathtools/#Match to filter content.")
  fmt.Fprintln(os.Stderr, "Mod time of output zip is set same as that of the first entry in zip.")
  fmt.Fprintln(os.Stderr, "Directory entries in input zips are skipped.")
  fmt.Fprintln(os.Stderr, "Duplicate files in input zips are not allowed.")
 }

 flag.Parse()

 outputZipPaths := flag.Args() // Get positional arguments for output zip paths

 if *rspFile == "" {
  log.Println("Error: Input RSP file (-i) is required.")
  flag.Usage()
  os.Exit(1)
 }
 if len(outputZipPaths) == 0 {
  log.Println("Error: At least one output ZIP file path must be provided.")
  flag.Usage()
  os.Exit(1)
 }

 log.SetFlags(log.Lshortfile)

 rsp, err := os.Open(*rspFile)
 if err != nil {
  fmt.Println("err: ", err)
  panic(err)
 }
 inputZips, err := response.ReadRspFile(rsp)
 if err != nil {
  panicOnError(err)
 }
 if len(inputZips) == 0 {
  panicOnError(fmt.Errorf("no input zips found"))
 }

 var zipReaders []zipReader
 var zipWriters []zipWriter

 for _, inputZip := range inputZips {
  reader, err := zip.OpenReader(inputZip)
  if err != nil {
   panicOnError(fmt.Errorf("warning: Failed to open input ZIP %s: %v", inputZip, err))
  }
  zipReaders = append(zipReaders, zipReader{
   reader:  &reader.Reader,
   zipPath: inputZip,
  })
  defer reader.Close()
 }
 for _, outputZipPath := range outputZipPaths {
  outputBuf := &bytes.Buffer{}
  zipWriters = append(zipWriters, zipWriter{
   writer:     zip.NewWriter(outputBuf),
   zipBytes:   outputBuf,
   outputPath: outputZipPath,
  })
 }

 processAndSplit(zipReaders, zipWriters)

 // Write the outputs from buffer
 for _, zipW := range zipWriters {
  zipW.writer.Close()
  writeIfChanged(zipW.outputPath, zipW.zipBytes)
 }
}

func processAndSplit(readers []zipReader, writers []zipWriter) {
 numSplits := len(writers)
 var allFileEntries []*zip.File
 filesSeenInAllZips := make(map[string]string)

 for _, zipR := range readers {
  for _, f := range zipR.reader.File {
   if filter != nil {
    if match, err := filter.Match(filepath.Base(f.Name)); err != nil {
     panicOnError(err)
    } else if !match {
     continue
    }
   }
   if _, seen := filesSeenInAllZips[f.Name]; !seen {
    filesSeenInAllZips[f.Name] = zipR.zipPath
    // Directories are skipped.
    if !f.FileInfo().IsDir() {
     allFileEntries = append(allFileEntries, f)
    }
   } else {
    if !f.FileInfo().IsDir() {
     panicOnError(fmt.Errorf("info: Duplicate file '%s' found in ZIP(s) '%s' and '%s'", f.Name, filesSeenInAllZips[f.Name], zipR.zipPath))
    }
   }
  }
 }

 if len(allFileEntries) == 0 {
  panicOnError(fmt.Errorf("no processable files found in input ZIPs"))
 }

 if numSplits > len(allFileEntries) {
  panicOnError(fmt.Errorf("number of splits '%d' more than total files '%d' in input zip(s)", numSplits, len(allFileEntries)))
 }

 // Determine how many actual files go into each split (approximately)
 filesPerSplitTarget := (len(allFileEntries) + numSplits - 1) / numSplits // Ceiling division
 currentOutputIndex := 0
 filesInCurrentSplit := 0

 for _, f := range allFileEntries {
  // If we reach max capacity for a split, use the next output
  if filesInCurrentSplit >= filesPerSplitTarget && currentOutputIndex < numSplits {
   currentOutputIndex++
   filesInCurrentSplit = 0
  }

  // Get the current zip writer
  currentWriter := writers[currentOutputIndex]
  if currentWriter.writer == nil {
   panicOnError(fmt.Errorf("zip Writer is nil"))
  }

  // f is from allFileEntries, its expected that its original reader is not
  // closed at this point. If it is, error will be thrown.
  err := currentWriter.writer.CopyFrom(f, f.Name)
  if err != nil {
   panicOnError(err)
  }

  filesInCurrentSplit++
 }
}

type multiFlag []string

func (m *multiFlag) String() string {
 return strings.Join(*m, " ")
}

func (m *multiFlag) Set(s string) error {
 *m = append(*m, s)
 return nil
}

func (m *multiFlag) Match(s string) (bool, error) {
 if m == nil {
  return false, nil
 }
 for _, f := range *m {
  if match, err := filepath.Match(f, s); err != nil {
   return false, err
  } else if match {
   return true, nil
  }
 }
 return false, nil
}

func writeIfChanged(outputFile string, buffer *bytes.Buffer) {
 if err := pathtools.WriteFileIfChanged(outputFile, buffer.Bytes(), 0666); err != nil {
  panicOnError(err)
 }
}

func panicOnError(err error) {
 fmt.Println("err: ", err)
 panic(err)
}

[Dauer der Verarbeitung: 0.22 Sekunden, vorverarbeitet 2026-06-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik