From 441ffd1ddf208363a4aad55a935dbf5d652d9bff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakob=20M=C3=B6ller?= Date: Wed, 21 Aug 2024 16:43:25 +0200 Subject: [PATCH] feat: git repo support --- api/oci/extensions/repositories/git/namespace.go | 7 ++++--- api/ocm/extensions/accessmethods/git/method.go | 5 ----- api/ocm/extensions/repositories/git/repo_test.go | 2 +- api/tech/git/fs.go | 6 +++--- api/tech/git/ref.go | 14 +++++++++++--- api/tech/git/resolver.go | 5 ++++- api/utils/accessio/downloader/git/downloader.go | 3 +-- 7 files changed, 24 insertions(+), 18 deletions(-) diff --git a/api/oci/extensions/repositories/git/namespace.go b/api/oci/extensions/repositories/git/namespace.go index 0683a8ac4d..2db42a820a 100644 --- a/api/oci/extensions/repositories/git/namespace.go +++ b/api/oci/extensions/repositories/git/namespace.go @@ -150,11 +150,12 @@ func GenerateCommitMessageForArtifact(operation Operation, artifact cpi.Artifact a := artifact.Artifact() var typ string - if artifact.IsManifest() { + switch { + case artifact.IsManifest(): typ = "manifest" - } else if artifact.IsIndex() { + case artifact.IsIndex(): typ = "index" - } else { + default: typ = "artifact" } diff --git a/api/ocm/extensions/accessmethods/git/method.go b/api/ocm/extensions/accessmethods/git/method.go index aaaf1149d9..cab76f0da8 100644 --- a/api/ocm/extensions/accessmethods/git/method.go +++ b/api/ocm/extensions/accessmethods/git/method.go @@ -3,7 +3,6 @@ package git import ( "fmt" "io" - "net/http" "github.com/go-git/go-git/v5/plumbing" "github.com/mandelsoft/goutils/errors" @@ -15,7 +14,6 @@ import ( "ocm.software/ocm/api/ocm/cpi/accspeccpi" "ocm.software/ocm/api/ocm/internal" "ocm.software/ocm/api/utils/accessio" - "ocm.software/ocm/api/utils/accessio/downloader" "ocm.software/ocm/api/utils/accessio/downloader/git" "ocm.software/ocm/api/utils/accessobj" "ocm.software/ocm/api/utils/blobaccess/blobaccess" @@ -45,9 +43,6 @@ type AccessSpec struct { // PathSpec is a path in the repository to download, can be a file or a regex matching multiple files PathSpec string `json:"pathSpec"` - - client *http.Client - downloader downloader.Downloader } // AccessSpecOptions defines a set of options which can be applied to the access spec. diff --git a/api/ocm/extensions/repositories/git/repo_test.go b/api/ocm/extensions/repositories/git/repo_test.go index 1dc71b8e22..c4fa9ae0f1 100644 --- a/api/ocm/extensions/repositories/git/repo_test.go +++ b/api/ocm/extensions/repositories/git/repo_test.go @@ -91,7 +91,7 @@ var _ = Describe("access method", func() { BeforeEach(func() { By("setting up local bare git repository to work against when pushing/updating") - billy := techgit.VFSBillyFS(remoteFS) + billy := Must(techgit.VFSBillyFS(remoteFS)) client.InstallProtocol("file", server.NewClient(server.NewFilesystemLoader(billy))) remoteRepo = Must(newBareTestRepo(billy, REMOTE_REPO, gitgo.InitOptions{})) // now that we have a bare repository, we can reference it via URL to access it like a remote repository diff --git a/api/tech/git/fs.go b/api/tech/git/fs.go index 0a74cd0e3a..1cbfe43608 100644 --- a/api/tech/git/fs.go +++ b/api/tech/git/fs.go @@ -16,18 +16,18 @@ import ( "github.com/mandelsoft/vfs/pkg/vfs" ) -func VFSBillyFS(fsToWrap vfs.FileSystem) billy.Filesystem { +func VFSBillyFS(fsToWrap vfs.FileSystem) (billy.Filesystem, error) { if fsToWrap == nil { fsToWrap = vfs.New(memoryfs.New()) } fi, err := fsToWrap.Stat(".") if err != nil || !fi.IsDir() { - panic(fmt.Errorf("invalid vfs: %v", err)) + return nil, fmt.Errorf("invalid vfs for billy conversion: %w", err) } return &fs{ vfs: fsToWrap, - } + }, nil } type fs struct { diff --git a/api/tech/git/ref.go b/api/tech/git/ref.go index 1512aa5ec2..df0161b52b 100644 --- a/api/tech/git/ref.go +++ b/api/tech/git/ref.go @@ -10,8 +10,10 @@ import ( giturls "github.com/whilp/git-urls" ) -const urlToRefSeparator = "@" -const refToPathSeparator = "#" +const ( + urlToRefSeparator = "@" + refToPathSeparator = "#" +) // refRegexp is a regular expression that matches a git ref string. // The ref string is expected to be in the format of: @@ -20,7 +22,13 @@ const refToPathSeparator = "#" // - url is the URL of the git repository // - ref is the git reference to checkout, if not specified, defaults to "HEAD" // - path is the path to the file or directory to use as the source, if not specified, defaults to the root of the repository. -var refRegexp = regexp.MustCompile(`^([^@#]+)(@[^#\n]+)?(#[^@\n]+)?`) +var refRegexp = regexp.MustCompile( + fmt.Sprintf( + `^([^%[1]s%[2]s]+)(%[1]s[^%[2]s\n]+)?(%[2]s[^%[1]s\n]+)?`, + urlToRefSeparator, + refToPathSeparator, + ), +) // gurl represents a git URL reference. // It contains the URL of the git repository, diff --git a/api/tech/git/resolver.go b/api/tech/git/resolver.go index 6c73ed2bf9..bc18bb83bc 100644 --- a/api/tech/git/resolver.go +++ b/api/tech/git/resolver.go @@ -79,7 +79,10 @@ func (c *client) Repository(ctx context.Context) (*git.Repository, error) { return c.repo, nil } - billyFS := VFSBillyFS(c.vfs) + billyFS, err := VFSBillyFS(c.vfs) + if err != nil { + return nil, err + } strg, err := GetStorage(billyFS) if err != nil { diff --git a/api/utils/accessio/downloader/git/downloader.go b/api/utils/accessio/downloader/git/downloader.go index 39d0be1884..a636c35951 100644 --- a/api/utils/accessio/downloader/git/downloader.go +++ b/api/utils/accessio/downloader/git/downloader.go @@ -29,7 +29,6 @@ type CloseableDownloader interface { // Downloader simply uses the default HTTP client to download the contents of a URL. type Downloader struct { cloneOpts *git.CloneOptions - grepOpts *git.GrepOptions matching *regexp.Regexp @@ -52,7 +51,7 @@ func NewDownloader(url string, ref string, path string, auth techgit.AuthMethod) Tags: git.NoTags, Depth: 0, }, - matching: regexp.MustCompile(fmt.Sprintf(`%s`, path)), + matching: regexp.MustCompile(path), buf: bytes.NewBuffer(make([]byte, 0, 4096)), storage: memory.NewStorage(), }