aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2024-06-11 13:12:26 +0200
committerMartin Polden <mpolden@mpolden.no>2024-06-11 14:12:40 +0200
commitca5464d58807dff9ea1e904996c3ee8b993b80eb (patch)
treed1e1ef6d566e37ec452db25ac480c24352d90321
parent6ef2120aa1e26aa55bbbf38a30340add4d1c4568 (diff)
Add support for .vespaignore
-rw-r--r--client/go/internal/cli/cmd/deploy_test.go33
-rw-r--r--client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/.vespaignore2
-rw-r--r--client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-dir/file1
-rw-r--r--client/go/internal/cli/cmd/testdata/applications/withSource/src/main/application/ignored-file0
-rw-r--r--client/go/internal/vespa/application.go75
-rw-r--r--client/go/internal/vespa/deploy.go3
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)