blob: 91b577f10e3d207ed21df8ddb8082a594e7db4b6 [file] [log] [blame]
// Copyright 2020-2021 Buf Technologies, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package buf
import (
"bytes"
"context"
"fmt"
"os"
"path/filepath"
"testing"
"github.com/bufbuild/buf/internal/buf/bufcli"
"github.com/bufbuild/buf/internal/pkg/osextended"
"github.com/bufbuild/buf/internal/pkg/storage/storagearchive"
"github.com/bufbuild/buf/internal/pkg/storage/storageos"
"github.com/stretchr/testify/require"
)
func TestWorkspaceDir(t *testing.T) {
// Directory paths contained within a workspace.
t.Parallel()
wd, err := osextended.Getwd()
require.NoError(t, err)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "dir", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/dir/proto/rpc.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "dir", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/dir/proto/rpc.proto:3:1:Files with package "example" must be within a directory "example" relative to root but were in directory ".".
testdata/workspace/success/dir/proto/rpc.proto:3:1:Package name "example" should be suffixed with a correctly formed version, such as "example.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "dir", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "dir", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/dir/other/proto/request.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "dir", "other", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/dir/other/proto/request.proto:3:1:Files with package "request" must be within a directory "request" relative to root but were in directory ".".
testdata/workspace/success/dir/other/proto/request.proto:3:1:Package name "request" should be suffixed with a correctly formed version, such as "request.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "dir", "other", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
fmt.Sprintf(`%s/testdata/workspace/success/dir/other/proto/request.proto:3:1:Files with package "request" must be within a directory "request" relative to root but were in directory ".".
%s/testdata/workspace/success/dir/other/proto/request.proto:3:1:Package name "request" should be suffixed with a correctly formed version, such as "request.v1".`, wd, wd),
"lint",
filepath.Join(wd, "testdata", "workspace", "success", "dir", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "dir"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/dir/other/proto/request.proto
testdata/workspace/success/dir/proto/rpc.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "dir"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/dir/other/proto/request.proto:3:1:Files with package "request" must be within a directory "request" relative to root but were in directory ".".
testdata/workspace/success/dir/other/proto/request.proto:3:1:Package name "request" should be suffixed with a correctly formed version, such as "request.v1".
testdata/workspace/success/dir/proto/rpc.proto:3:1:Files with package "example" must be within a directory "example" relative to root but were in directory ".".
testdata/workspace/success/dir/proto/rpc.proto:3:1:Package name "example" should be suffixed with a correctly formed version, such as "example.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "dir"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "breaking"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/breaking/other/proto/request.proto
testdata/workspace/success/breaking/proto/rpc.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "breaking"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/breaking/other/proto/request.proto:5:1:Previously present field "1" with name "name" on message "Request" was deleted.
testdata/workspace/success/breaking/proto/rpc.proto:8:5:Field "1" with name "request" on message "RPC" changed option "json_name" from "req" to "request".
testdata/workspace/success/breaking/proto/rpc.proto:8:21:Field "1" on message "RPC" changed name from "req" to "request".`,
"breaking",
filepath.Join("testdata", "workspace", "success", "breaking"),
"--against",
filepath.Join("testdata", "workspace", "success", "dir"),
)
}
func TestWorkspaceArchiveDir(t *testing.T) {
// Archive that defines a workspace at the root of the archive.
t.Parallel()
zipDir := createZipFromDir(
t,
filepath.Join("testdata", "workspace", "success", "dir"),
"archive.zip",
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join(zipDir, "archive.zip#subdir=proto"),
)
testRunStdout(
t,
nil,
0,
`proto/rpc.proto`,
"ls-files",
filepath.Join(zipDir, "archive.zip#subdir=proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`proto/rpc.proto:3:1:Files with package "example" must be within a directory "example" relative to root but were in directory ".".
proto/rpc.proto:3:1:Package name "example" should be suffixed with a correctly formed version, such as "example.v1".`,
"lint",
filepath.Join(zipDir, "archive.zip#subdir=proto"),
)
}
func TestWorkspaceNestedArchive(t *testing.T) {
// Archive that defines a workspace in a sub-directory to the root.
t.Parallel()
zipDir := createZipFromDir(
t,
filepath.Join("testdata", "workspace", "success", "nested"),
"archive.zip",
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join(zipDir, "archive.zip#subdir=proto/internal"),
)
testRunStdout(
t,
nil,
0,
`proto/internal/internal.proto`,
"ls-files",
filepath.Join(zipDir, "archive.zip#subdir=proto/internal"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`proto/internal/internal.proto:3:1:Files with package "internal" must be within a directory "internal" relative to root but were in directory ".".
proto/internal/internal.proto:3:1:Package name "internal" should be suffixed with a correctly formed version, such as "internal.v1".`,
"lint",
filepath.Join(zipDir, "archive.zip#subdir=proto/internal"),
)
}
func TestWorkspaceGit(t *testing.T) {
// Directory paths specified as a git reference within a workspace.
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "../../../../../../../.git#ref=HEAD,subdir=internal/buf/cmd/buf/testdata/workspace/success/dir/proto"),
)
testRunStdout(
t,
nil,
0,
`internal/buf/cmd/buf/testdata/workspace/success/dir/proto/rpc.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "../../../../../../../.git#ref=HEAD,subdir=internal/buf/cmd/buf/testdata/workspace/success/dir/proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`internal/buf/cmd/buf/testdata/workspace/success/dir/proto/rpc.proto:3:1:Files with package "example" must be within a directory "example" relative to root but were in directory ".".
internal/buf/cmd/buf/testdata/workspace/success/dir/proto/rpc.proto:3:1:Package name "example" should be suffixed with a correctly formed version, such as "example.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "../../../../../../../.git#ref=HEAD,subdir=internal/buf/cmd/buf/testdata/workspace/success/dir/proto"),
)
}
func TestWorkspaceDetached(t *testing.T) {
// The workspace doesn't include the 'proto' directory, so
// its contents aren't included in the workspace.
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "detached", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/detached/proto/rpc.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "detached", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/detached/proto/rpc.proto:3:1:Files with package "example" must be within a directory "example" relative to root but were in directory ".".
testdata/workspace/success/detached/proto/rpc.proto:3:1:Package name "example" should be suffixed with a correctly formed version, such as "example.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "detached", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "detached", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/detached/other/proto/request.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "detached", "other", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/detached/other/proto/request.proto:3:1:Files with package "request" must be within a directory "request" relative to root but were in directory ".".
testdata/workspace/success/detached/other/proto/request.proto:3:1:Package name "request" should be suffixed with a correctly formed version, such as "request.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "detached", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "detached"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/detached/other/proto/request.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "detached"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/detached/other/proto/request.proto:3:1:Files with package "request" must be within a directory "request" relative to root but were in directory ".".
testdata/workspace/success/detached/other/proto/request.proto:3:1:Package name "request" should be suffixed with a correctly formed version, such as "request.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "detached"),
)
}
func TestWorkspaceNoModuleConfig(t *testing.T) {
// The workspace points to modules that don't contain a buf.yaml.
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "noconfig", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/noconfig/proto/rpc.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "noconfig", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/noconfig/proto/rpc.proto:3:1:Files with package "example" must be within a directory "example" relative to root but were in directory ".".
testdata/workspace/success/noconfig/proto/rpc.proto:3:1:Package name "example" should be suffixed with a correctly formed version, such as "example.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "noconfig", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "noconfig", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/noconfig/other/proto/request.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "noconfig", "other", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/noconfig/other/proto/request.proto:3:1:Files with package "request" must be within a directory "request" relative to root but were in directory ".".
testdata/workspace/success/noconfig/other/proto/request.proto:3:1:Package name "request" should be suffixed with a correctly formed version, such as "request.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "noconfig", "other", "proto"),
)
}
func TestWorkspaceWithLock(t *testing.T) {
// The workspace points to a module that includes a buf.lock, but
// the listed dependency is defined in the workspace so the module
// cache is unused.
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "lock", "a"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/lock/a/a.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "lock", "a"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/lock/a/a.proto:3:1:Files with package "a" must be within a directory "a" relative to root but were in directory ".".
testdata/workspace/success/lock/a/a.proto:3:1:Package name "a" should be suffixed with a correctly formed version, such as "a.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "lock", "a"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "lock", "b"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/lock/b/b.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "lock", "b"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/lock/b/b.proto:3:1:Files with package "b" must be within a directory "b" relative to root but were in directory ".".
testdata/workspace/success/lock/b/b.proto:3:1:Package name "b" should be suffixed with a correctly formed version, such as "b.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "lock", "b"),
)
}
func TestWorkspaceWithTransitiveDependencies(t *testing.T) {
// The workspace points to a module that includes transitive
// dependencies (i.e. a depends on b, and b depends on c).
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "transitive", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/transitive/proto/a.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "transitive", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/transitive/proto/a.proto:3:1:Files with package "a" must be within a directory "a" relative to root but were in directory ".".
testdata/workspace/success/transitive/proto/a.proto:3:1:Package name "a" should be suffixed with a correctly formed version, such as "a.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "transitive", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "transitive", "private", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/transitive/private/proto/b.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "transitive", "private", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/transitive/private/proto/b.proto:3:1:Files with package "b" must be within a directory "b" relative to root but were in directory ".".
testdata/workspace/success/transitive/private/proto/b.proto:3:1:Package name "b" should be suffixed with a correctly formed version, such as "b.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "transitive", "private", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "transitive", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/transitive/other/proto/c.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "transitive", "other", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/transitive/other/proto/c.proto:3:1:Files with package "c" must be within a directory "c" relative to root but were in directory ".".
testdata/workspace/success/transitive/other/proto/c.proto:3:1:Package name "c" should be suffixed with a correctly formed version, such as "c.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "transitive", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "transitive"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/transitive/other/proto/c.proto
testdata/workspace/success/transitive/private/proto/b.proto
testdata/workspace/success/transitive/proto/a.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "transitive"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/transitive/other/proto/c.proto:3:1:Files with package "c" must be within a directory "c" relative to root but were in directory ".".
testdata/workspace/success/transitive/other/proto/c.proto:3:1:Package name "c" should be suffixed with a correctly formed version, such as "c.v1".
testdata/workspace/success/transitive/private/proto/b.proto:3:1:Files with package "b" must be within a directory "b" relative to root but were in directory ".".
testdata/workspace/success/transitive/private/proto/b.proto:3:1:Package name "b" should be suffixed with a correctly formed version, such as "b.v1".
testdata/workspace/success/transitive/proto/a.proto:3:1:Files with package "a" must be within a directory "a" relative to root but were in directory ".".
testdata/workspace/success/transitive/proto/a.proto:3:1:Package name "a" should be suffixed with a correctly formed version, such as "a.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "transitive"),
)
}
func TestWorkspaceWithDiamondDependency(t *testing.T) {
// The workspace points to a module that includes a diamond
// dependency (i.e. a depends on b and c, and b depends on c).
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "diamond", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/diamond/proto/a.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "diamond", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/diamond/proto/a.proto:3:1:Files with package "a" must be within a directory "a" relative to root but were in directory ".".
testdata/workspace/success/diamond/proto/a.proto:3:1:Package name "a" should be suffixed with a correctly formed version, such as "a.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "diamond", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "diamond", "private", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/diamond/private/proto/b.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "diamond", "private", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/diamond/private/proto/b.proto:3:1:Files with package "b" must be within a directory "b" relative to root but were in directory ".".
testdata/workspace/success/diamond/private/proto/b.proto:3:1:Package name "b" should be suffixed with a correctly formed version, such as "b.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "diamond", "private", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "diamond", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/diamond/other/proto/c.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "diamond", "other", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/diamond/other/proto/c.proto:3:1:Files with package "c" must be within a directory "c" relative to root but were in directory ".".
testdata/workspace/success/diamond/other/proto/c.proto:3:1:Package name "c" should be suffixed with a correctly formed version, such as "c.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "diamond", "other", "proto"),
)
}
func TestWorkspaceSymlink(t *testing.T) {
// The workspace includes valid symlinks.
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "symlink"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/symlink/a/a.proto
testdata/workspace/success/symlink/b/b.proto
testdata/workspace/success/symlink/c/c.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "symlink"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/symlink/a/a.proto:3:1:Files with package "a" must be within a directory "a" relative to root but were in directory ".".
testdata/workspace/success/symlink/a/a.proto:3:1:Package name "a" should be suffixed with a correctly formed version, such as "a.v1".
testdata/workspace/success/symlink/b/b.proto:3:1:Files with package "b" must be within a directory "b" relative to root but were in directory ".".
testdata/workspace/success/symlink/b/b.proto:3:1:Package name "b" should be suffixed with a correctly formed version, such as "b.v1".
testdata/workspace/success/symlink/c/c.proto:3:1:Files with package "c" must be within a directory "c" relative to root but were in directory ".".
testdata/workspace/success/symlink/c/c.proto:3:1:Package name "c" should be suffixed with a correctly formed version, such as "c.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "symlink"),
)
}
func TestWorkspaceWKT(t *testing.T) {
// The workspace includes multiple images that import the same
// well-known type (empty.proto).
t.Parallel()
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "wkt", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/wkt/other/proto/c/c.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "wkt", "other", "proto"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/wkt/other/proto/c/c.proto:6:1:Package name "c" should be suffixed with a correctly formed version, such as "c.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "wkt", "other", "proto"),
)
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "success", "wkt"),
)
testRunStdout(
t,
nil,
0,
`testdata/workspace/success/wkt/other/proto/c/c.proto
testdata/workspace/success/wkt/proto/a/a.proto
testdata/workspace/success/wkt/proto/b/b.proto`,
"ls-files",
filepath.Join("testdata", "workspace", "success", "wkt"),
)
testRunStdout(
t,
nil,
bufcli.ExitCodeFileAnnotation,
`testdata/workspace/success/wkt/other/proto/c/c.proto:6:1:Package name "c" should be suffixed with a correctly formed version, such as "c.v1".
testdata/workspace/success/wkt/proto/a/a.proto:3:1:Package name "a" should be suffixed with a correctly formed version, such as "a.v1".
testdata/workspace/success/wkt/proto/b/b.proto:3:1:Package name "b" should be suffixed with a correctly formed version, such as "b.v1".`,
"lint",
filepath.Join("testdata", "workspace", "success", "wkt"),
)
testRunStdout(
t,
nil,
0,
``,
"breaking",
filepath.Join("testdata", "workspace", "success", "wkt"),
"--against",
filepath.Join("testdata", "workspace", "success", "wkt"),
)
}
func TestWorkspaceBreakingFail(t *testing.T) {
// The two workspaces define a different number of
// images, so it's impossible to verify compatibility.
testRunStdout(
t,
nil,
0,
``,
"build",
filepath.Join("testdata", "workspace", "fail", "breaking"),
)
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: input contained 1 images, whereas against contained 2 images.`,
"breaking",
filepath.Join("testdata", "workspace", "fail", "breaking"),
"--against",
filepath.Join("testdata", "workspace", "success", "breaking"),
)
}
func TestWorkspaceDuplicateFail(t *testing.T) {
// The workspace includes multiple images that define the same file.
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: foo.proto exists in multiple locations: testdata/workspace/fail/duplicate/other/proto/foo.proto testdata/workspace/fail/duplicate/proto/foo.proto.`,
"build",
filepath.Join("testdata", "workspace", "fail", "duplicate"),
)
}
func TestWorkspaceNotExistFail(t *testing.T) {
// The directory defined in the workspace does not exist.
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: module "notexist" listed in testdata/workspace/fail/notexist/buf.work contains no .proto files.`,
"build",
filepath.Join("testdata", "workspace", "fail", "notexist"),
)
}
func TestWorkspaceJumpContextFail(t *testing.T) {
// The workspace directories cannot jump context.
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: ../breaking/other/proto: is outside the context directory.`,
"build",
filepath.Join("testdata", "workspace", "fail", "jumpcontext"),
)
}
func TestWorkspaceSymlinkFail(t *testing.T) {
// The workspace includes a symlink that isn't buildable.
testRunStdoutStderr(
t,
nil,
bufcli.ExitCodeFileAnnotation,
``,
`testdata/workspace/fail/symlink/b/b.proto:5:8:c.proto: does not exist`,
"build",
filepath.Join("testdata", "workspace", "fail", "symlink"),
)
}
func TestWorkspaceAbsoluteFail(t *testing.T) {
// The buf.work file cannot specify absolute paths.
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: module "/home/buf" listed in testdata/workspace/fail/absolute/buf.work must be a relative path.`,
"build",
filepath.Join("testdata", "workspace", "fail", "absolute"),
)
}
func TestWorkspaceDirOverlapFail(t *testing.T) {
// The buf.work file cannot specify overlapping diretories.
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: module "foo" contains module "foo/bar" in testdata/workspace/fail/diroverlap/buf.work; see https://docs.buf.build/faq for more details.`,
"build",
filepath.Join("testdata", "workspace", "fail", "diroverlap"),
)
}
func TestWorkspaceInputOverlapFail(t *testing.T) {
// The target input cannot overlap with any of the directories defined
// in the workspace.
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: failed to build input "proto/buf" because it is contained by module "proto" listed in testdata/workspace/fail/overlap/buf.work; see https://docs.buf.build/faq for more details.`,
"build",
filepath.Join("testdata", "workspace", "fail", "overlap", "proto", "buf"),
)
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: failed to build input "other" because it contains module "other/proto" listed in testdata/workspace/success/dir/buf.work; see https://docs.buf.build/faq for more details.`,
"build",
filepath.Join("testdata", "workspace", "success", "dir", "other"),
)
}
func TestWorkspaceRegularFileFail(t *testing.T) {
// Build directory inputs must be directories.
testRunStdoutStderr(
t,
nil,
1,
``,
`Failure: testdata/workspace/success/dir/proto/rpc.proto: not a directory.`,
"build",
filepath.Join("testdata", "workspace", "success", "dir", "proto", "rpc.proto"),
)
}
func createZipFromDir(t *testing.T, rootPath string, archiveName string) string {
t.Helper()
zipDir := filepath.Join(os.TempDir(), rootPath)
t.Cleanup(
func() {
require.NoError(t, os.RemoveAll(zipDir))
},
)
require.NoError(t, os.MkdirAll(zipDir, 0755))
storageosProvider := storageos.NewProvider(storageos.ProviderWithSymlinks())
testdataBucket, err := storageosProvider.NewReadWriteBucket(
rootPath,
storageos.ReadWriteBucketWithSymlinksIfSupported(),
)
require.NoError(t, err)
buffer := bytes.NewBuffer(nil)
require.NoError(t, storagearchive.Zip(
context.Background(),
testdataBucket,
buffer,
true,
))
zipBucket, err := storageosProvider.NewReadWriteBucket(
zipDir,
storageos.ReadWriteBucketWithSymlinksIfSupported(),
)
require.NoError(t, err)
zipCloser, err := zipBucket.Put(
context.Background(),
archiveName,
)
require.NoError(t, err)
t.Cleanup(
func() {
require.NoError(t, zipCloser.Close())
},
)
_, err = zipCloser.Write(buffer.Bytes())
require.NoError(t, err)
return zipDir
}