diff options
author | Martin Polden <mpolden@mpolden.no> | 2024-06-11 13:12:26 +0200 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2024-06-11 14:12:40 +0200 |
commit | ca5464d58807dff9ea1e904996c3ee8b993b80eb (patch) | |
tree | d1e1ef6d566e37ec452db25ac480c24352d90321 | |
parent | 6ef2120aa1e26aa55bbbf38a30340add4d1c4568 (diff) |
Add support for .vespaignore
6 files changed, 70 insertions, 44 deletions
diff --git a/client/go/internal/cli/cmd/deploy_test.go b/client/go/internal/cli/cmd/deploy_test.go index 4771d107ba4..8d1c202e554 100644 --- a/client/go/internal/cli/cmd/deploy_test.go +++ b/client/go/internal/cli/cmd/deploy_test.go @@ -5,8 +5,10 @@ package cmd import ( + "archive/zip" "bytes" "io" + "os" "path/filepath" "strconv" "strings" @@ -134,8 +136,7 @@ func TestPrepareZip(t *testing.T) { } func TestActivateZip(t *testing.T) { - assertActivate("testdata/applications/withTarget/target/application.zip", - []string{"activate", "--wait=0", "testdata/applications/withTarget/target/application.zip"}, t) + assertActivate([]string{"activate", "--wait=0", "testdata/applications/withTarget/target/application.zip"}, t) } func TestDeployZip(t *testing.T) { @@ -185,6 +186,32 @@ func TestDeployApplicationDirectoryWithPomAndEmptyTarget(t *testing.T) { stderr.String()) } +func TestDeployIncludesExpectedFiles(t *testing.T) { + cli, stdout, _ := newTestCLI(t) + client := &mock.HTTPClient{} + cli.httpClient = client + assert.Nil(t, cli.Run("deploy", "--wait=0", "testdata/applications/withSource")) + applicationPackage := "testdata/applications/withSource/src/main/application" + assert.Equal(t, + "\nSuccess: Deployed '"+applicationPackage+"' with session ID 0\n", + stdout.String()) + + zipName := filepath.Join(t.TempDir(), "tmp.zip") + f, err := os.Create(zipName) + assert.Nil(t, err) + if _, err := io.Copy(f, client.LastRequest.Body); err != nil { + t.Fatal(err) + } + zr, err := zip.OpenReader(zipName) + assert.Nil(t, err) + defer zr.Close() + var zipFiles []string + for _, f := range zr.File { + zipFiles = append(zipFiles, f.Name) + } + assert.Equal(t, []string{".vespaignore", "hosts.xml", "schemas/msmarco.sd", "services.xml"}, zipFiles) +} + func TestDeployApplicationPackageErrorWithUnexpectedNonJson(t *testing.T) { assertApplicationPackageError(t, "deploy", 401, "Raw text error", @@ -251,7 +278,7 @@ func assertPrepare(applicationPackage string, arguments []string, t *testing.T) assert.Equal(t, "PUT", client.Requests[1].Method) } -func assertActivate(applicationPackage string, arguments []string, t *testing.T) { +func assertActivate(arguments []string, t *testing.T) { t.Helper() client := &mock.HTTPClient{} cli, stdout, _ := newTestCLI(t) diff --git a/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/.vespaignore b/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/.vespaignore new file mode 100644 index 00000000000..24ca95c5b1e --- /dev/null +++ b/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/.vespaignore @@ -0,0 +1,2 @@ +ignored-dir/ +ignored-file diff --git a/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-dir/file b/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-dir/file new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-dir/file @@ -0,0 +1 @@ + diff --git a/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-file b/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-file new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-file diff --git a/client/go/internal/vespa/application.go b/client/go/internal/vespa/application.go index a65fb41d783..618d23b6bab 100644 --- a/client/go/internal/vespa/application.go +++ b/client/go/internal/vespa/application.go @@ -11,6 +11,7 @@ import ( "strings" "github.com/vespa-engine/vespa/client/go/internal/ioutil" + "github.com/vespa-engine/vespa/client/go/internal/vespa/ignore" ) type ApplicationPackage struct { @@ -73,7 +74,7 @@ func (ap *ApplicationPackage) Validate() error { func isZip(filename string) bool { return filepath.Ext(filename) == ".zip" } -func zipDir(dir string, destination string) error { +func zipDir(dir string, destination string, ignores *ignore.List) error { if !ioutil.Exists(dir) { message := "'" + dir + "' should be an application package zip or dir, but does not exist" return errors.New(message) @@ -82,22 +83,23 @@ func zipDir(dir string, destination string) error { message := "'" + dir + "' should be an application package dir, but is a (non-zip) file" return errors.New(message) } - file, err := os.Create(destination) if err != nil { message := "Could not create a temporary zip file for the application package: " + err.Error() return errors.New(message) } defer file.Close() - w := zip.NewWriter(file) defer w.Close() - walker := func(path string, info os.FileInfo, err error) error { if err != nil { return err } - if ignorePackageFile(filepath.Base(path)) { + zipPath, err := filepath.Rel(dir, path) + if err != nil { + return err + } + if ignores.Match(zipPath) { if info.IsDir() { return filepath.SkipDir } @@ -106,22 +108,16 @@ func zipDir(dir string, destination string) error { if info.IsDir() { return nil } - file, err := os.Open(path) + srcFile, err := os.Open(path) if err != nil { return err } - defer file.Close() - - zippath, err := filepath.Rel(dir, path) + defer srcFile.Close() + zipFile, err := w.Create(zipPath) if err != nil { return err } - zipfile, err := w.Create(zippath) - if err != nil { - return err - } - - _, err = io.Copy(zipfile, file) + _, err = io.Copy(zipFile, srcFile) if err != nil { return err } @@ -130,39 +126,38 @@ func zipDir(dir string, destination string) error { return filepath.Walk(dir, walker) } -func ignorePackageFile(name string) bool { - switch name { - case ".DS_Store": - return true +func (ap *ApplicationPackage) openZip(name string) (io.ReadCloser, error) { + f, err := os.Open(name) + if err != nil { + return nil, fmt.Errorf("could not open application package at '%s': %w", ap.Path, err) } - return false + return f, nil } func (ap *ApplicationPackage) zipReader(test bool) (io.ReadCloser, error) { - zipFile := ap.Path + path := ap.Path if test { - zipFile = ap.TestPath + path = ap.TestPath } - if !ap.IsZip() { - tempZip, err := os.CreateTemp("", "vespa") - if err != nil { - return nil, fmt.Errorf("could not create a temporary zip file for the application package: %w", err) - } - defer func() { - tempZip.Close() - os.Remove(tempZip.Name()) - // TODO: Caller must remove temporary file - }() - if err := zipDir(zipFile, tempZip.Name()); err != nil { - return nil, err - } - zipFile = tempZip.Name() + if ap.IsZip() { + return ap.openZip(path) } - f, err := os.Open(zipFile) + tmp, err := os.CreateTemp("", "vespa") if err != nil { - return nil, fmt.Errorf("could not open application package at '%s': %w", ap.Path, err) + return nil, fmt.Errorf("could not create a temporary zip file for the application package: %w", err) } - return f, nil + defer func() { + tmp.Close() + os.Remove(tmp.Name()) + }() + ignores, err := ignore.ReadFile(filepath.Join(path, ".vespaignore")) + if err != nil { + return nil, fmt.Errorf("could not read .vespaignore: %w", err) + } + if err := zipDir(path, tmp.Name(), ignores); err != nil { + return nil, err + } + return ap.openZip(tmp.Name()) } func (ap *ApplicationPackage) Unzip(test bool) (string, error) { @@ -283,7 +278,7 @@ func findApplicationPackage(zipOrDir string, options PackageOptions) (Applicatio testPath := existingPath(filepath.Join(zipOrDir, "src", "test", "application")) return ApplicationPackage{Path: path, TestPath: testPath}, nil } - // Application without Java components + // Application without Maven/Java if ioutil.Exists(filepath.Join(zipOrDir, "services.xml")) { testPath := "" if ioutil.Exists(filepath.Join(zipOrDir, "tests")) { diff --git a/client/go/internal/vespa/deploy.go b/client/go/internal/vespa/deploy.go index df74d1def8b..ca03c82f6d9 100644 --- a/client/go/internal/vespa/deploy.go +++ b/client/go/internal/vespa/deploy.go @@ -20,6 +20,7 @@ import ( "github.com/vespa-engine/vespa/client/go/internal/ioutil" "github.com/vespa-engine/vespa/client/go/internal/version" + "github.com/vespa-engine/vespa/client/go/internal/vespa/ignore" ) var ( @@ -197,7 +198,7 @@ func fetchFromConfigServer(deployment DeploymentOptions, path string) error { return err } zipFile := filepath.Join(tmpDir, "application.zip") - if err := zipDir(dir, zipFile); err != nil { + if err := zipDir(dir, zipFile, &ignore.List{}); err != nil { return err } return os.Rename(zipFile, path) |