Skip to content

Commit

Permalink
Merge pull request #490 from zong-zhe/split-client-pkg
Browse files Browse the repository at this point in the history
refactor: split visitor from client
  • Loading branch information
Peefy committed Sep 25, 2024
2 parents b7efafd + ce25ea3 commit b4d396a
Show file tree
Hide file tree
Showing 11 changed files with 187 additions and 49 deletions.
32 changes: 32 additions & 0 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import (
"kcl-lang.io/kpm/pkg/runner"
"kcl-lang.io/kpm/pkg/settings"
"kcl-lang.io/kpm/pkg/utils"
"kcl-lang.io/kpm/pkg/visitor"
)

// KpmClient is the client of kpm.
Expand Down Expand Up @@ -1720,6 +1721,37 @@ func (c *KpmClient) FetchOciManifestIntoJsonStr(opts opt.OciFetchOptions) (strin
return manifestJson, nil
}

// NewVisitor is a factory function to create a new Visitor.
func NewVisitor(source downloader.Source, kpmcli *KpmClient) visitor.Visitor {
PkgVisitor := &visitor.PkgVisitor{
Settings: kpmcli.GetSettings(),
LogWriter: kpmcli.logWriter,
}

if source.IsRemote() {
return &visitor.RemoteVisitor{
PkgVisitor: PkgVisitor,
Downloader: kpmcli.DepDownloader,
InsecureSkipTLSverify: kpmcli.insecureSkipTLSverify,
}
} else if source.IsLocalTarPath() || source.IsLocalTgzPath() {
return visitor.NewArchiveVisitor(PkgVisitor)
} else if source.IsLocalPath() {
rootPath, err := source.FindRootPath()
if err != nil {
return nil
}
kclmodpath := filepath.Join(rootPath, constants.KCL_MOD)
if utils.DirExists(kclmodpath) {
return PkgVisitor
} else {
return visitor.NewVirtualPkgVisitor(PkgVisitor)
}
} else {
return nil
}
}

// createDepRef will create a dependency reference for the dependency saved on the local filesystem.
// On the unix-like system, it will create a symbolic link.
// On the windows system, it will create a junction.
Expand Down
23 changes: 16 additions & 7 deletions pkg/client/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (

"kcl-lang.io/kpm/pkg/downloader"
pkg "kcl-lang.io/kpm/pkg/package"
"kcl-lang.io/kpm/pkg/visitor"
)

// ResolveOption is the option for resolving dependencies.
Expand Down Expand Up @@ -95,16 +96,24 @@ func (dr *DepsResolver) Resolve(options ...ResolveOption) error {
// visitorSelectorFunc selects the visitor for the source.
// For remote source, it will use the RemoteVisitor and enable the cache.
// For local source, it will use the PkgVisitor.
visitorSelectorFunc := func(source *downloader.Source) (Visitor, error) {
visitorSelectorFunc := func(source *downloader.Source) (visitor.Visitor, error) {
if source.IsRemote() {
PkgVisitor := NewRemoteVisitor(NewPkgVisitor(dr.kpmClient))
PkgVisitor.EnableCache = opts.EnableCache
if opts.CachePath == "" {
PkgVisitor.CachePath = dr.kpmClient.homePath
var cachePath string
if opts.CachePath != "" {
cachePath = opts.CachePath
} else {
PkgVisitor.CachePath = opts.CachePath
cachePath = dr.kpmClient.homePath
}
return PkgVisitor, nil
return &visitor.RemoteVisitor{
PkgVisitor: &visitor.PkgVisitor{
Settings: &dr.kpmClient.settings,
LogWriter: dr.kpmClient.logWriter,
},
Downloader: dr.kpmClient.DepDownloader,
InsecureSkipTLSverify: dr.kpmClient.insecureSkipTLSverify,
EnableCache: opts.EnableCache,
CachePath: cachePath,
}, nil
} else {
return NewVisitor(*source, dr.kpmClient), nil
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/visitor/test_data/test_visit_dir/kcl.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "test_visit_dir"
edition = "v0.10.0"
version = "0.0.1"
Empty file.
1 change: 1 addition & 0 deletions pkg/visitor/test_data/test_visit_dir/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The_first_kcl_program = 'Hello World!'
4 changes: 4 additions & 0 deletions pkg/visitor/test_data/test_visit_tar/kcl.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[package]
name = "test_visit_tar"
edition = "v0.10.0"
version = "0.0.1"
Empty file.
1 change: 1 addition & 0 deletions pkg/visitor/test_data/test_visit_tar/main.k
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The_first_kcl_program = 'Hello World!'
Binary file not shown.
69 changes: 27 additions & 42 deletions pkg/client/visitor.go → pkg/visitor/visitor.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
package client
package visitor

import (
"fmt"
"io"
"os"
"path/filepath"

Expand All @@ -10,6 +11,7 @@ import (
"kcl-lang.io/kpm/pkg/downloader"
"kcl-lang.io/kpm/pkg/opt"
pkg "kcl-lang.io/kpm/pkg/package"
"kcl-lang.io/kpm/pkg/settings"
"kcl-lang.io/kpm/pkg/utils"
)

Expand All @@ -22,14 +24,8 @@ type Visitor interface {

// PkgVisitor is the visitor for visiting a local package.
type PkgVisitor struct {
kpmcli *KpmClient
}

// NewPkgVisitor creates a new PkgVisitor.
func NewPkgVisitor(kpmcli *KpmClient) *PkgVisitor {
return &PkgVisitor{
kpmcli: kpmcli,
}
Settings *settings.Settings
LogWriter io.Writer
}

// Visit visits a local package.
Expand All @@ -39,12 +35,15 @@ func (pv *PkgVisitor) Visit(s *downloader.Source, v visitFunc) error {
}
// Find the root path of the source.
// There must be a kcl.mod file in the root path.
rootPath, err := s.FindRootPath()
modPath, err := s.FindRootPath()
if err != nil {
return err
}

kclPkg, err := pv.kpmcli.LoadPkgFromPath(rootPath)
kclPkg, err := pkg.LoadKclPkgWithOpts(
pkg.WithPath(modPath),
pkg.WithSettings(pv.Settings),
)
if err != nil {
return err
}
Expand Down Expand Up @@ -90,8 +89,10 @@ func (vpv *VirtualPkgVisitor) Visit(s *downloader.Source, v visitFunc) error {
// RemoteVisitor is the visitor for visiting a remote package.
type RemoteVisitor struct {
*PkgVisitor
EnableCache bool
CachePath string
EnableCache bool
CachePath string
Downloader downloader.Downloader
InsecureSkipTLSverify bool
}

// NewRemoteVisitor creates a new RemoteVisitor.
Expand All @@ -118,21 +119,21 @@ func (rv *RemoteVisitor) Visit(s *downloader.Source, v visitFunc) error {
tmpDir = filepath.Join(tmpDir, constants.GitScheme)
}

credCli, err := rv.kpmcli.GetCredsClient()
credCli, err := downloader.LoadCredentialFile(rv.Settings.CredentialsFile)
if err != nil {
return err
}

defer os.RemoveAll(tmpDir)
err = rv.kpmcli.DepDownloader.Download(*downloader.NewDownloadOptions(
err = rv.Downloader.Download(*downloader.NewDownloadOptions(
downloader.WithLocalPath(tmpDir),
downloader.WithSource(*s),
downloader.WithLogWriter(rv.kpmcli.GetLogWriter()),
downloader.WithSettings(*rv.kpmcli.GetSettings()),
downloader.WithLogWriter(rv.LogWriter),
downloader.WithSettings(*rv.Settings),
downloader.WithCredsClient(credCli),
downloader.WithCachePath(rv.CachePath),
downloader.WithEnableCache(rv.EnableCache),
downloader.WithInsecureSkipTLSverify(rv.kpmcli.insecureSkipTLSverify),
downloader.WithInsecureSkipTLSverify(rv.InsecureSkipTLSverify),
))

if err != nil {
Expand All @@ -146,7 +147,10 @@ func (rv *RemoteVisitor) Visit(s *downloader.Source, v visitFunc) error {
}
}

kclPkg, err := rv.kpmcli.LoadPkgFromPath(pkgPath)
kclPkg, err := pkg.LoadKclPkgWithOpts(
pkg.WithPath(pkgPath),
pkg.WithSettings(rv.Settings),
)
if err != nil {
return err
}
Expand Down Expand Up @@ -212,33 +216,14 @@ func (av *ArchiveVisitor) Visit(s *downloader.Source, v visitFunc) error {
return err
}

kclPkg, err := av.kpmcli.LoadPkgFromPath(tmpDir)
kclPkg, err := pkg.LoadKclPkgWithOpts(
pkg.WithPath(tmpDir),
pkg.WithSettings(av.Settings),
)

if err != nil {
return err
}

return v(kclPkg)
}

// NewVisitor is a factory function to create a new Visitor.
func NewVisitor(source downloader.Source, kpmcli *KpmClient) Visitor {
if source.IsRemote() {
return NewRemoteVisitor(NewPkgVisitor(kpmcli))
} else if source.IsLocalTarPath() || source.IsLocalTgzPath() {
return NewArchiveVisitor(NewPkgVisitor(kpmcli))
} else if source.IsLocalPath() {
rootPath, err := source.FindRootPath()
if err != nil {
return nil
}
kclmodpath := filepath.Join(rootPath, constants.KCL_MOD)
if utils.DirExists(kclmodpath) {
return NewPkgVisitor(kpmcli)
} else {
return NewVirtualPkgVisitor(NewPkgVisitor(kpmcli))
}
} else {
return nil
}
}
102 changes: 102 additions & 0 deletions pkg/visitor/visitor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package visitor

import (
"bytes"
"os"
"path/filepath"
"testing"

"gotest.tools/v3/assert"
"kcl-lang.io/kpm/pkg/downloader"
pkg "kcl-lang.io/kpm/pkg/package"
"kcl-lang.io/kpm/pkg/settings"
)

const testDataDir = "test_data"

func getTestDir(subDir string) string {
pwd, _ := os.Getwd()
testDir := filepath.Join(pwd, testDataDir)
testDir = filepath.Join(testDir, subDir)

return testDir
}

func TestVisitPkgDir(t *testing.T) {
pkgDir := getTestDir("test_visit_dir")
pVisitor := PkgVisitor{}
source, err := downloader.NewSourceFromStr(pkgDir)
if err != nil {
t.Fatal(err)
}

err = pVisitor.Visit(source, func(pkg *pkg.KclPkg) error {
assert.Equal(t, pkg.GetPkgName(), "test_visit_dir")
assert.Equal(t, pkg.GetPkgVersion(), "0.0.1")
return nil
})
assert.NilError(t, err)
}

func TestVisitPkgTar(t *testing.T) {
pkgTar := filepath.Join(getTestDir("test_visit_tar"), "test_visit_tar-0.0.1.tar")
pVisitor := PkgVisitor{}
source, err := downloader.NewSourceFromStr(pkgTar)
if err != nil {
t.Fatal(err)
}

err = pVisitor.Visit(source, func(pkg *pkg.KclPkg) error {
assert.Equal(t, pkg.GetPkgName(), "test_visit_tar")
assert.Equal(t, pkg.GetPkgVersion(), "0.0.1")
return nil
})
assert.NilError(t, err)
}

func TestVisitPkgRemote(t *testing.T) {
var buf bytes.Buffer
remotePkgVisitor := RemoteVisitor{
PkgVisitor: &PkgVisitor{
LogWriter: &buf,
Settings: settings.GetSettings(),
},
Downloader: &downloader.DepDownloader{},
}

tests := []struct {
sourceStr string
expectedPkgName string
expectedPkgVer string
expectedLog string
}{
{
sourceStr: "oci://ghcr.io/kcl-lang/helloworld?tag=0.1.2",
expectedPkgName: "helloworld",
expectedPkgVer: "0.1.2",
expectedLog: "downloading 'kcl-lang/helloworld:0.1.2' from 'ghcr.io/kcl-lang/helloworld:0.1.2'\n",
},
{
sourceStr: "git://github.com/kcl-lang/flask-demo-kcl-manifests.git?branch=main",
expectedPkgName: "flask_manifests",
expectedPkgVer: "0.0.1",
expectedLog: "cloning 'https://github.com/kcl-lang/flask-demo-kcl-manifests.git' with branch 'main'\n",
},
}

for _, tt := range tests {
buf.Reset()
source, err := downloader.NewSourceFromStr(tt.sourceStr)
if err != nil {
t.Fatal(err)
}

err = remotePkgVisitor.Visit(source, func(pkg *pkg.KclPkg) error {
assert.Equal(t, pkg.GetPkgName(), tt.expectedPkgName)
assert.Equal(t, pkg.GetPkgVersion(), tt.expectedPkgVer)
return nil
})
assert.Equal(t, buf.String(), tt.expectedLog)
assert.NilError(t, err)
}
}

0 comments on commit b4d396a

Please sign in to comment.