예제 #1
0
파일: repo.go 프로젝트: shazow/go-vcs
func (fs *hgFSNative) lstat(path string) (*util.FileInfo, []byte, error) {
	path = filepath.Clean(internal.Rel(path))

	rec, ent, err := fs.getEntry(path)
	if os.IsNotExist(err) {
		// check if path is a dir (dirs are not in hg's manifest, so we need to
		// hack around to get them).
		fi, err := fs.dirStat(path)
		return fi, nil, err
	}
	if err != nil {
		return nil, nil, standardizeHgError(err)
	}

	fi := fs.fileInfo(ent)

	// read data to determine file size
	data, err := fs.readFile(rec)
	if err != nil {
		return nil, nil, err
	}
	fi.Size_ = int64(len(data))

	return fi, data, nil
}
예제 #2
0
파일: repo.go 프로젝트: emil2k/go-vcs
func (fs *gitFSCmd) ReadDir(path string) ([]os.FileInfo, error) {
	fs.repoEditLock.RLock()
	defer fs.repoEditLock.RUnlock()
	// Trailing slash is necessary to ls-tree under the dir (not just
	// to list the dir's tree entry in its parent dir).
	return fs.lsTree(filepath.Clean(internal.Rel(path)) + "/")
}
예제 #3
0
파일: repo.go 프로젝트: shazow/go-vcs
func (fs *gitFSLibGit2) Lstat(path string) (os.FileInfo, error) {
	fs.repoEditLock.RLock()
	defer fs.repoEditLock.RUnlock()

	path = filepath.Clean(internal.Rel(path))

	mtime, err := fs.getModTime()
	if err != nil {
		return nil, err
	}

	if path == "." {
		return &util.FileInfo{Mode_: os.ModeDir, ModTime_: mtime}, nil
	}

	e, err := fs.getEntry(path)
	if err != nil {
		return nil, err
	}

	fi, err := fs.makeFileInfo(path, e)
	if err != nil {
		return nil, err
	}
	fi.ModTime_ = mtime

	return fi, nil
}
예제 #4
0
파일: repo.go 프로젝트: emil2k/go-vcs
func (fs *gitFSCmd) Lstat(path string) (os.FileInfo, error) {
	fs.repoEditLock.RLock()
	defer fs.repoEditLock.RUnlock()

	path = filepath.Clean(internal.Rel(path))

	if path == "." {
		// Special case root, which is not returned by `git ls-tree`.
		mtime, err := fs.getModTimeFromGitLog(path)
		if err != nil {
			return nil, err
		}
		return &util.FileInfo{Mode_: os.ModeDir, ModTime_: mtime}, nil
	}

	fis, err := fs.lsTree(path)
	if err != nil {
		return nil, err
	}
	if len(fis) == 0 {
		return nil, &os.PathError{Op: "ls-tree", Path: path, Err: os.ErrNotExist}
	}

	return fis[0], nil
}
예제 #5
0
파일: repo.go 프로젝트: shazow/go-vcs
func (fs *gitFSLibGit2) ReadDir(path string) ([]os.FileInfo, error) {
	fs.repoEditLock.RLock()
	defer fs.repoEditLock.RUnlock()

	path = filepath.Clean(internal.Rel(path))

	var subtree *git2go.Tree
	if path == "." {
		subtree = fs.tree
	} else {
		e, err := fs.getEntry(path)
		if err != nil {
			return nil, err
		}

		subtree, err = fs.repo.LookupTree(e.Id)
		if err != nil {
			return nil, err
		}
	}

	fis := make([]os.FileInfo, int(subtree.EntryCount()))
	for i := uint64(0); i < subtree.EntryCount(); i++ {
		e := subtree.EntryByIndex(i)
		fi, err := fs.makeFileInfo(filepath.Join(path, e.Name), e)
		if err != nil {
			return nil, err
		}
		fis[i] = fi
	}

	return fis, nil
}
예제 #6
0
파일: repo.go 프로젝트: shazow/go-vcs
func (fs *hgFSNative) ReadDir(path string) ([]os.FileInfo, error) {
	path = internal.Rel(path)
	m, err := fs.getManifest(fs.at)
	if err != nil {
		return nil, err
	}

	var fis []os.FileInfo
	subdirs := make(map[string]struct{})

	var dirPrefix string
	if path := filepath.Clean(path); path == "." {
		dirPrefix = ""
	} else {
		dirPrefix = path + "/"
	}
	for _, e := range m {
		if !strings.HasPrefix(e.FileName, dirPrefix) {
			continue
		}
		name := strings.TrimPrefix(e.FileName, dirPrefix)
		dir := filepath.Dir(name)
		if dir == "." {
			fis = append(fis, fs.fileInfo(&e))
		} else {
			subdir := strings.SplitN(dir, "/", 2)[0]
			if _, seen := subdirs[subdir]; !seen {
				fis = append(fis, &util.FileInfo{Name_: subdir, Mode_: os.ModeDir})
				subdirs[subdir] = struct{}{}
			}
		}
	}
	return fis, nil
}
예제 #7
0
파일: vfs.go 프로젝트: emil2k/go-vcs
func (fs *filesystem) Lstat(path string) (os.FileInfo, error) {
	path = filepath.Clean(internal.Rel(path))

	mtime, err := fs.getModTime()
	if err != nil {
		return nil, err
	}

	if path == "." {
		return &util.FileInfo{Mode_: os.ModeDir, ModTime_: mtime}, nil
	}

	e, err := fs.tree.GetTreeEntryByPath(path)
	if err != nil {
		return nil, err
	}

	fi, err := fs.makeFileInfo(path, e)
	if err != nil {
		return nil, err
	}
	fi.ModTime_ = mtime

	return fi, nil
}
예제 #8
0
파일: vfs.go 프로젝트: emil2k/go-vcs
func (fs *filesystem) ReadDir(path string) ([]os.FileInfo, error) {
	path = filepath.Clean(internal.Rel(path))

	var subtree *git.Tree
	if path == "." {
		subtree = fs.tree
	} else {
		e, err := fs.tree.GetTreeEntryByPath(path)
		if err != nil {
			return nil, err
		}

		// FIXME: This looks redundant?
		subtree, err = fs.repo.GetTree(e.Id.String())
		if err != nil {
			return nil, err
		}
	}

	entries, err := subtree.ListEntries()
	if err != nil {
		return nil, err
	}

	fis := make([]os.FileInfo, 0, len(entries))
	for _, e := range entries {
		fi, err := fs.makeFileInfo(filepath.Join(path, e.Name()), e)
		if err != nil {
			return nil, err
		}
		fis = append(fis, fi)
	}

	return fis, nil
}
예제 #9
0
파일: repo.go 프로젝트: alexsaveliev/go-vcs
func (fs *hgFSCmd) ReadDir(path string) ([]os.FileInfo, error) {
	path = filepath.Clean(internal.Rel(path))
	// This combination of --include and --exclude opts gets all the files in
	// the dir specified by path, plus all files one level deeper (but no
	// deeper). This lets us list the files *and* subdirs in the dir without
	// needlessly listing recursively.
	cmd := exec.Command("hg", "locate", "--rev="+string(fs.at), "--include="+path, "--exclude="+filepath.Clean(path)+"/*/*/*")
	cmd.Dir = fs.dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		return nil, fmt.Errorf("exec `hg cat` failed: %s. Output was:\n\n%s", err, out)
	}

	subdirs := make(map[string]struct{})
	prefix := []byte(path + "/")
	files := bytes.Split(out, []byte{'\n'})
	var fis []os.FileInfo
	for _, nameb := range files {
		nameb = bytes.TrimPrefix(nameb, prefix)
		if len(nameb) == 0 {
			continue
		}
		if bytes.Contains(nameb, []byte{'/'}) {
			subdir := strings.SplitN(string(nameb), "/", 2)[0]
			if _, seen := subdirs[subdir]; !seen {
				fis = append(fis, &util.FileInfo{Name_: subdir, Mode_: os.ModeDir})
				subdirs[subdir] = struct{}{}
			}
			continue
		}
		fis = append(fis, &util.FileInfo{Name_: filepath.Base(string(nameb))})
	}

	return fis, nil
}
예제 #10
0
파일: vfs.go 프로젝트: emil2k/go-vcs
func (fs *filesystem) Open(name string) (vfs.ReadSeekCloser, error) {
	name = internal.Rel(name)

	b, err := fs.readFileBytes(name)
	if err != nil {
		return nil, err
	}
	return util.NopCloser{ReadSeeker: bytes.NewReader(b)}, nil
}
예제 #11
0
파일: repo.go 프로젝트: emil2k/go-vcs
func (fs *gitFSCmd) Open(name string) (vfs.ReadSeekCloser, error) {
	name = internal.Rel(name)
	fs.repoEditLock.RLock()
	defer fs.repoEditLock.RUnlock()
	b, err := fs.readFileBytes(name)
	if err != nil {
		return nil, err
	}
	return util.NopCloser{bytes.NewReader(b)}, nil
}
예제 #12
0
파일: repo.go 프로젝트: shazow/go-vcs
func (fs *hgFSNative) Open(name string) (vfs.ReadSeekCloser, error) {
	name = internal.Rel(name)
	rec, _, err := fs.getEntry(name)
	if err != nil {
		return nil, standardizeHgError(err)
	}

	data, err := fs.readFile(rec)
	if err != nil {
		return nil, err
	}
	return util.NopCloser{bytes.NewReader(data)}, nil
}
예제 #13
0
파일: repo.go 프로젝트: alexsaveliev/go-vcs
func (fs *hgFSCmd) Open(name string) (vfs.ReadSeekCloser, error) {
	name = internal.Rel(name)
	cmd := exec.Command("hg", "cat", "--rev="+string(fs.at), "--", name)
	cmd.Dir = fs.dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		if bytes.Contains(out, []byte("no such file in rev")) {
			return nil, os.ErrNotExist
		}
		return nil, fmt.Errorf("exec `hg cat` failed: %s. Output was:\n\n%s", err, out)
	}
	return util.NopCloser{bytes.NewReader(out)}, nil
}
예제 #14
0
파일: repo.go 프로젝트: shazow/go-vcs
func (fs *gitFSLibGit2) Stat(path string) (os.FileInfo, error) {
	fs.repoEditLock.RLock()
	defer fs.repoEditLock.RUnlock()

	path = filepath.Clean(internal.Rel(path))

	mtime, err := fs.getModTime()
	if err != nil {
		return nil, err
	}

	if path == "." {
		return &util.FileInfo{Mode_: os.ModeDir, ModTime_: mtime}, nil
	}

	e, err := fs.getEntry(path)
	if err != nil {
		return nil, err
	}

	if e.Filemode == git2go.FilemodeLink {
		// dereference symlink
		b, err := fs.repo.LookupBlob(e.Id)
		if err != nil {
			return nil, err
		}

		derefPath := string(b.Contents())
		fi, err := fs.Lstat(derefPath)
		if err != nil {
			return nil, err
		}

		// Use original filename.
		fi.(*util.FileInfo).Name_ = filepath.Base(path)

		return fi, nil
	}

	fi, err := fs.makeFileInfo(path, e)
	if err != nil {
		return nil, err
	}
	fi.ModTime_ = mtime

	return fi, nil
}
예제 #15
0
파일: repo.go 프로젝트: alexsaveliev/go-vcs
func (fs *hgFSCmd) Stat(path string) (os.FileInfo, error) {
	// TODO(sqs): follow symlinks (as Stat is required to do)

	path = internal.Rel(path)
	var mtime time.Time

	cmd := exec.Command("hg", "log", "-l1", `--template={date|date}`,
		"-r "+string(fs.at)+":0", "--", path)
	cmd.Dir = fs.dir
	out, err := cmd.CombinedOutput()
	if err != nil {
		return nil, err
	}

	mtime, err = time.Parse("Mon Jan 02 15:04:05 2006 -0700",
		strings.Trim(string(out), "\n"))
	if err != nil {
		log.Println(err)
		// return nil, err
	}

	// this just determines if the file exists.
	cmd = exec.Command("hg", "locate", "--rev="+string(fs.at), "--", path)
	cmd.Dir = fs.dir
	err = cmd.Run()
	if err != nil {
		// hg doesn't track dirs, so use a workaround to see if path is a dir.
		if _, err := fs.ReadDir(path); err == nil {
			return &util.FileInfo{Name_: filepath.Base(path), Mode_: os.ModeDir,
				ModTime_: mtime}, nil
		}
		return nil, os.ErrNotExist
	}

	// read file to determine file size
	f, err := fs.Open(path)
	if err != nil {
		return nil, err
	}
	defer f.Close()
	data, err := ioutil.ReadAll(f)

	return &util.FileInfo{Name_: filepath.Base(path), Size_: int64(len(data)),
		ModTime_: mtime}, nil
}
예제 #16
0
파일: vfs.go 프로젝트: emil2k/go-vcs
func (fs *filesystem) Stat(path string) (os.FileInfo, error) {
	path = filepath.Clean(internal.Rel(path))

	mtime, err := fs.getModTime()
	if err != nil {
		return nil, err
	}

	if path == "." {
		return &util.FileInfo{Mode_: os.ModeDir, ModTime_: mtime}, nil
	}

	e, err := fs.tree.GetTreeEntryByPath(path)
	if err != nil {
		return nil, err
	}

	if e.EntryMode() == git.ModeSymlink {
		// Dereference symlink.
		b, err := e.Blob().Data()
		if err != nil {
			return nil, err
		}
		fi, err := fs.Lstat(string(b))
		if err != nil {
			return nil, err
		}

		// Use original filename.
		fi.(*util.FileInfo).Name_ = filepath.Base(path)
		return fi, nil
	}

	fi, err := fs.makeFileInfo(path, e)
	if err != nil {
		return nil, err
	}
	fi.ModTime_ = mtime

	return fi, nil
}
예제 #17
0
파일: repo.go 프로젝트: shazow/go-vcs
func (fs *hgFSNative) Stat(path string) (os.FileInfo, error) {
	path = internal.Rel(path)
	fi, data, err := fs.lstat(path)
	if err != nil {
		return nil, err
	}

	if fi.Mode()&os.ModeSymlink != 0 {
		// derefence symlink
		derefPath := string(data)
		fi, err := fs.Lstat(derefPath)
		if err != nil {
			return nil, err
		}

		fi.(*util.FileInfo).Name_ = filepath.Base(path)
		return fi, nil
	}

	return fi, nil
}
예제 #18
0
파일: repo.go 프로젝트: emil2k/go-vcs
func (fs *gitFSCmd) Stat(path string) (os.FileInfo, error) {
	path = internal.Rel(path)

	fs.repoEditLock.RLock()
	defer fs.repoEditLock.RUnlock()

	fi, err := fs.Lstat(path)
	if err != nil {
		return nil, err
	}

	if fi.Mode()&os.ModeSymlink != 0 {
		// Deref symlink.
		si := fi.Sys().(vcs.SymlinkInfo)
		fi2, err := fs.Lstat(si.Dest)
		if err != nil {
			return nil, err
		}
		fi2.(*util.FileInfo).Name_ = fi.Name()
		return fi2, nil
	}

	return fi, nil
}
예제 #19
0
파일: repo.go 프로젝트: alexsaveliev/go-vcs
func (fs *hgFSCmd) Lstat(path string) (os.FileInfo, error) {
	return fs.Stat(internal.Rel(path))
}