Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/tools/tools/treble/hacksaw/workspace/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 6 kB image not shown  

Quelle  copier.go   Sprache: unbekannt

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

// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package workspace

import (
 "fmt"
 "io"
 "io/ioutil"
 "os"
 "path/filepath"
 "strings"
)

type FileCopier struct {
}

func NewFileCopier() *FileCopier {
 var f FileCopier
 return &f
}

func (f FileCopier) GetIsGitProjectFunc(codebaseDir string, gitProjects []string) func(string) (bool, error) {
 //Convert the git project list to a set to speed up lookups
 gitProjectSet := make(map[string]struct{})
 var exists = struct{}{}
 for _, project := range gitProjects {
  gitProjectSet[project] = exists
 }

 return func(pathToCheck string) (bool, error) {
  var err error
  if pathToCheck, err = filepath.Rel(codebaseDir, pathToCheck); err != nil {
   return false, err
  }
  if _, ok := gitProjectSet[pathToCheck]; ok {
   return true, err
  }
  return false, err
 }
}

func (f FileCopier) GetContainsGitProjectFunc(codebaseDir string, gitProjects []string) func(string) (bool, error) {
 //Extract the set of dirs that contain git projects
 containsGitSet := make(map[string]struct{})
 var exists = struct{}{}
 for _, project := range gitProjects {
  for dir := project; dir != "." && dir != "/"; dir = filepath.Dir(dir) {
   containsGitSet[dir] = exists
  }
 }

 return func(pathToCheck string) (bool, error) {
  var err error
  if pathToCheck, err = filepath.Rel(codebaseDir, pathToCheck); err != nil {
   return false, err
  }
  if _, ok := containsGitSet[pathToCheck]; ok {
   return true, err
  }
  return false, err
 }
}

//gitProjects is relative to codebaseDir
func (f FileCopier) Copy(codebaseDir string, gitProjects []string, workspaceDir string) error {
 isGitProject := f.GetIsGitProjectFunc(codebaseDir, gitProjects)
 containsGitProject := f.GetContainsGitProjectFunc(codebaseDir, gitProjects)

 return filepath.Walk(codebaseDir,
  func(path string, info os.FileInfo, err error) error {
   if err != nil {
    return err
   }

   // Copy files
   if !info.IsDir() {
    return f.CopyNode(info, codebaseDir, path, workspaceDir)
   }

   if path == filepath.Clean(codebaseDir) {
    return nil
   }

   // Always skip traversal of root repo directories
   if path == filepath.Join(codebaseDir, ".repo") {
    return filepath.SkipDir
   }

   // Skip all git projects
   var isGitProj bool
   if isGitProj, err = isGitProject(path); err != nil {
    return err
   }
   if isGitProj {
    return filepath.SkipDir
   }

   // Copy over files
   var containsGitProj bool
   if containsGitProj, err = containsGitProject(path); err != nil {
    return err
   }
   if !containsGitProj {
    destPath, err := f.GetDestPath(codebaseDir, path, workspaceDir)
    if err != nil {
     return err
    }
    if err = f.CopyDirRecursive(info, path, destPath); err != nil {
     return err
    }
    return filepath.SkipDir
   }
   return f.CopyNode(info, codebaseDir, path, workspaceDir)
  })
}

func (f FileCopier) GetDestPath(codebaseDir, sourcePath, workspaceDir string) (string, error) {
 if !strings.HasPrefix(sourcePath+"/", codebaseDir+"/") {
  return "", fmt.Errorf("%s is not contained in %s", sourcePath, codebaseDir)
 }
 relPath, err := filepath.Rel(codebaseDir, sourcePath)
 if err != nil {
  return "", err
 }
 destPath := filepath.Join(workspaceDir, relPath)
 return destPath, err
}

// Copy any single file, symlink or dir non-recursively
// sourcePath must be contained in codebaseDir
func (f FileCopier) CopyNode(sourceInfo os.FileInfo, codebaseDir, sourcePath, workspaceDir string) error {
 destPath, err := f.GetDestPath(codebaseDir, sourcePath, workspaceDir)
 if err != nil {
  return err
 }
 switch {
 case sourceInfo.Mode()&os.ModeSymlink == os.ModeSymlink:
  return f.CopySymlink(sourcePath, destPath)
 case sourceInfo.Mode().IsDir():
  return f.CopyDirOnly(sourceInfo, destPath)
 default:
  return f.CopyFile(sourceInfo, sourcePath, destPath)
 }
}

func (f FileCopier) CopySymlink(sourcePath string, destPath string) error {
 // Skip symlink if it already exists at the destination
 _, err := os.Lstat(destPath)
 if err == nil {
  return nil
 }

 target, err := os.Readlink(sourcePath)
 if err != nil {
  return err
 }

 return os.Symlink(target, destPath)
}

// CopyDirOnly copies a directory non-recursively
// sourcePath must be contained in codebaseDir
func (f FileCopier) CopyDirOnly(sourceInfo os.FileInfo, destPath string) error {
 _, err := os.Stat(destPath)
 if err == nil {
  // Dir already exists, nothing to do
  return err
 } else if os.IsNotExist(err) {
  return os.Mkdir(destPath, sourceInfo.Mode())
 }
 return err
}

// CopyFile copies a single file
// sourcePath must be contained in codebaseDir
func (f FileCopier) CopyFile(sourceInfo os.FileInfo, sourcePath, destPath string) error {
 //Skip file if it already exists at the destination
 _, err := os.Lstat(destPath)
 if err == nil {
  return nil
 }

 sourceFile, err := os.Open(sourcePath)
 if err != nil {
  return err
 }
 defer sourceFile.Close()

 destFile, err := os.Create(destPath)
 if err != nil {
  return err
 }
 defer destFile.Close()

 _, err = io.Copy(destFile, sourceFile)
 if err != nil {
  return err
 }
 return os.Chmod(destPath, sourceInfo.Mode())
}

func (f FileCopier) CopyDirRecursive(sourceInfo os.FileInfo, sourcePath, destPath string) error {
 if err := f.CopyDirOnly(sourceInfo, destPath); err != nil {
  return err
 }
 childNodes, err := ioutil.ReadDir(sourcePath)
 if err != nil {
  return err
 }
 for _, childInfo := range childNodes {
  childSourcePath := filepath.Join(sourcePath, childInfo.Name())
  childDestPath := filepath.Join(destPath, childInfo.Name())
  switch {
  case childInfo.Mode()&os.ModeSymlink == os.ModeSymlink:
   if err = f.CopySymlink(childSourcePath, childDestPath); err != nil {
    return err
   }
  case childInfo.Mode().IsDir():
   if err = f.CopyDirRecursive(childInfo, childSourcePath, childDestPath); err != nil {
    return err
   }
  default:
   if err = f.CopyFile(childInfo, childSourcePath, childDestPath); err != nil {
    return err
   }
  }
 }
 return err
}

[Dauer der Verarbeitung: 0.24 Sekunden, vorverarbeitet 2026-06-27]