mirror of https://github.com/knative/func.git
fix: full clone of template repos on add (#904)
* full clone remote repos on write * use filepath to parse path
This commit is contained in:
parent
c60079d792
commit
564a34b3f5
|
|
@ -338,11 +338,8 @@ func TestRepositories_Remove(t *testing.T) {
|
||||||
// TestRepositories_URL ensures that a repository populates its URL member
|
// TestRepositories_URL ensures that a repository populates its URL member
|
||||||
// from the git repository's origin url (if it is a git repo and exists)
|
// from the git repository's origin url (if it is a git repo and exists)
|
||||||
func TestRepositories_URL(t *testing.T) {
|
func TestRepositories_URL(t *testing.T) {
|
||||||
// FIXME: This test is temporarily disabled. See not in Repository.Write
|
if runtime.GOOS == "windows" {
|
||||||
// in short: as a side-effect of removing the double-clone, the in-memory
|
t.Skip("TODO fix this test on Windows CI") // TODO fix this
|
||||||
// repo is insufficient as it does not include a .git directory.
|
|
||||||
if true {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uri := TestRepoURI(RepositoriesTestRepo, t)
|
uri := TestRepoURI(RepositoriesTestRepo, t)
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package function
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
"net/url"
|
"net/url"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
|
|
@ -449,24 +450,60 @@ func (r *Repository) Runtime(name string) (runtime Runtime, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write all files in the repository to the given path.
|
// Write all files in the repository to the given path.
|
||||||
func (r *Repository) Write(path string) error {
|
func (r *Repository) Write(path string) (err error) {
|
||||||
// NOTE: Writing internal .git directory does not work
|
fs := r.FS // The FS to copy
|
||||||
//
|
|
||||||
// A quirk of the git library's implementation is that the filesystem
|
|
||||||
// returned does not include the .git directory. This is usually not an
|
|
||||||
// issue when utilizing the repository's filesystem (for writing templates),
|
|
||||||
// but it does cause problems here (used for installing a repo locally) where
|
|
||||||
// we effectively want a full clone.
|
|
||||||
// TODO: switch to using a temp directory?
|
|
||||||
|
|
||||||
return copy(".", path, r.FS) // copy 'all' to 'dest' from 'FS'
|
// NOTE
|
||||||
|
// We re-load in-memory git repos via a temp directory to avoid what
|
||||||
|
// appears to be a missing .git directory in the default worktree FS.
|
||||||
|
//
|
||||||
|
// This missing .git dir is usually not an issue when utilizing the
|
||||||
|
// repository's filesystem (for writing templates, etc), but it does cause
|
||||||
|
// problems here where we are writing the entire repository to disk (cloning).
|
||||||
|
// We effectively want a full clone with a working tree. So here we do a
|
||||||
|
// plain clone first to a temp directory and then copy the files on disk
|
||||||
|
// using a regular file copy operation which thus includes the repo metadata.
|
||||||
|
if _, ok := r.FS.(billyFilesystem); ok {
|
||||||
|
var (
|
||||||
|
tempDir string
|
||||||
|
clone *git.Repository
|
||||||
|
wt *git.Worktree
|
||||||
|
)
|
||||||
|
if tempDir, err = ioutil.TempDir("", "func"); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if clone, err = git.PlainClone(tempDir, false, // not bare
|
||||||
|
&git.CloneOptions{URL: r.uri, Depth: 1, Tags: git.NoTags,
|
||||||
|
RecurseSubmodules: git.NoRecurseSubmodules}); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if wt, err = clone.Worktree(); err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fs = billyFilesystem{fs: wt.Filesystem}
|
||||||
|
}
|
||||||
|
return copy(".", path, fs)
|
||||||
}
|
}
|
||||||
|
|
||||||
// URL attempts to read the remote git origin URL of the repository. Best
|
// URL attempts to read the remote git origin URL of the repository. Best
|
||||||
// effort; returns empty string if the repository is not a git repo or the repo
|
// effort; returns empty string if the repository is not a git repo or the repo
|
||||||
// has been mutated beyond recognition on disk (ex: removing the origin remote)
|
// has been mutated beyond recognition on disk (ex: removing the origin remote)
|
||||||
func (r *Repository) URL() string {
|
func (r *Repository) URL() string {
|
||||||
repo, err := git.PlainOpen(r.uri)
|
uri := r.uri
|
||||||
|
|
||||||
|
// The default builtin repository is indicated by an empty URI.
|
||||||
|
// It has no remote URL, and without this check the current working directory
|
||||||
|
// would be checked.
|
||||||
|
if uri == "" {
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
// git.PlainOpen does not seem to
|
||||||
|
if strings.HasPrefix(uri, "file://") {
|
||||||
|
uri = filepath.FromSlash(r.uri[7:])
|
||||||
|
}
|
||||||
|
|
||||||
|
repo, err := git.PlainOpen(uri)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "" // not a git repository
|
return "" // not a git repository
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue