Eine aufbereitete Darstellung der Quelle

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

Benutzer

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.20 Sekunden, vorverarbeitet 2026-06-27]

                                                                                                                                                                                                                                                                                                                                                                                                     


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