Exemplo n.º 1
0
// SymbolicWalk is like filepath.Walk, but it supports the root being a
// symbolic link. It will still not follow symbolic links deeper down in
// the file structure
func SymbolicWalk(fs afero.Fs, root string, walker filepath.WalkFunc) error {

	// Handle the root first
	fileInfo, err := lstatIfOs(fs, root)

	if err != nil || !fileInfo.IsDir() {
		return nil
	}

	if err != nil {
		return walker(root, nil, err)
	}

	if err := walker(root, fileInfo, err); err != nil && err != filepath.SkipDir {
		return err
	}

	rootContent, err := afero.ReadDir(fs, root)

	if err != nil {
		return walker(root, nil, err)
	}

	for _, fi := range rootContent {
		afero.Walk(fs, filepath.Join(root, fi.Name()), walker)
	}

	return nil

}
Exemplo n.º 2
0
// checkDir returns true if dst is a non-empty directory and src is a file
func (s *Syncer) checkDir(dst, src string) (b bool, err error) {
	// read file info
	dstat, err := os.Stat(dst)
	if os.IsNotExist(err) {
		return false, nil
	} else if err != nil {
		return false, err
	}
	sstat, err := os.Stat(src)
	if err != nil {
		return false, err
	}

	// return false is dst is not a directory or src is a directory
	if !dstat.IsDir() || sstat.IsDir() {
		return false, nil
	}

	// dst is a directory and src is a file
	// check if dst is non-empty
	// read dst directory

	files, err := afero.ReadDir(s.DestFs, dst)
	if err != nil {
		return false, err
	}
	if len(files) > 0 {
		return true, nil
	}
	return false, nil
}
Exemplo n.º 3
0
// readDirFromWorkingDir listst the directory content relative to the
// configured WorkingDir.
func readDirFromWorkingDir(i interface{}) ([]os.FileInfo, error) {

	path := cast.ToString(i)

	list, err := afero.ReadDir(hugofs.WorkingDir(), path)

	if err != nil {
		return nil, fmt.Errorf("Failed to read Directory %s with error message %s", path, err)
	}

	return list, nil
}
Exemplo n.º 4
0
func globFiles(fs afero.Fs, targetPath, pattern string) []string {
	children, err := afero.ReadDir(fs, targetPath)

	if err != nil {
		panic(err)
	}

	var matches []string

	for _, child := range children {
		if glob.Glob(pattern, child.Name()) {
			matches = append(matches, path.Join(targetPath, child.Name()))
		}
	}

	return matches
}
Exemplo n.º 5
0
// SymbolicWalk is like filepath.Walk, but it supports the root being a
// symbolic link. It will still not follow symbolic links deeper down in
// the file structure
func SymbolicWalk(fs afero.Fs, root string, walker filepath.WalkFunc) error {

	// Sanity check
	if len(root) < 4 {
		return WalkRootTooShortError
	}

	// Handle the root first
	fileInfo, realPath, err := getRealFileInfo(fs, root)

	if err != nil {
		return walker(root, nil, err)
	}

	if !fileInfo.IsDir() {
		return fmt.Errorf("Cannot walk regular file %s", root)
	}

	if err := walker(realPath, fileInfo, err); err != nil && err != filepath.SkipDir {
		return err
	}

	rootContent, err := afero.ReadDir(fs, root)

	if err != nil {
		return walker(root, nil, err)
	}

	for _, fi := range rootContent {
		if err := afero.Walk(fs, filepath.Join(root, fi.Name()), walker); err != nil {
			return err
		}
	}

	return nil

}
Exemplo n.º 6
0
// sync updates dst to match with src, handling both files and directories.
func (s *Syncer) sync(dst, src string) {
	// sync permissions and modification times after handling content
	defer s.syncstats(dst, src)

	// read files info
	dstat, err := s.DestFs.Stat(dst)
	if err != nil && !os.IsNotExist(err) {
		panic(err)
	}
	sstat, err := s.SrcFs.Stat(src)
	if err != nil && os.IsNotExist(err) {
		return // src was deleted before we could copy it
	}
	check(err)

	if !sstat.IsDir() {
		// src is a file
		// delete dst if its a directory
		if dstat != nil && dstat.IsDir() {
			check(s.DestFs.RemoveAll(dst))
		}
		if !s.equal(dst, src) {
			// perform copy
			df, err := s.DestFs.Create(dst)
			check(err)
			defer df.Close()
			sf, err := s.SrcFs.Open(src)
			if os.IsNotExist(err) {
				return
			}
			check(err)
			defer sf.Close()
			_, err = io.Copy(df, sf)
			if os.IsNotExist(err) {
				return
			}
			check(err)
		}
		return
	}

	// src is a directory
	// make dst if necessary
	if dstat == nil {
		// dst does not exist; create directory
		check(s.DestFs.MkdirAll(dst, 0755)) // permissions will be synced later
	} else if !dstat.IsDir() {
		// dst is a file; remove and create directory
		check(s.DestFs.Remove(dst))
		check(s.DestFs.MkdirAll(dst, 0755)) // permissions will be synced later
	}

	// go through sf files and sync them
	files, err := afero.ReadDir(s.SrcFs, src)
	if os.IsNotExist(err) {
		return
	}
	check(err)
	// make a map of filenames for quick lookup; used in deletion
	// deletion below
	m := make(map[string]bool, len(files))
	for _, file := range files {
		dst2 := filepath.Join(dst, file.Name())
		src2 := filepath.Join(src, file.Name())
		s.sync(dst2, src2)
		m[file.Name()] = true
	}

	// delete files from dst that does not exist in src
	if s.Delete {
		files, err = afero.ReadDir(s.DestFs, dst)
		check(err)
		for _, file := range files {
			if !m[file.Name()] {
				check(s.DestFs.RemoveAll(filepath.Join(dst, file.Name())))
			}
		}
	}
}