aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/cli/internal/packagemanager/infer_root_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'cli/internal/packagemanager/infer_root_test.go')
-rw-r--r--cli/internal/packagemanager/infer_root_test.go347
1 files changed, 347 insertions, 0 deletions
diff --git a/cli/internal/packagemanager/infer_root_test.go b/cli/internal/packagemanager/infer_root_test.go
new file mode 100644
index 0000000..2e37a80
--- /dev/null
+++ b/cli/internal/packagemanager/infer_root_test.go
@@ -0,0 +1,347 @@
+package packagemanager
+
+import (
+ "reflect"
+ "testing"
+
+ "github.com/vercel/turbo/cli/internal/turbopath"
+ "gotest.tools/v3/assert"
+)
+
+func TestInferRoot(t *testing.T) {
+ type file struct {
+ path turbopath.AnchoredSystemPath
+ content []byte
+ }
+
+ tests := []struct {
+ name string
+ fs []file
+ executionDirectory turbopath.AnchoredSystemPath
+ rootPath turbopath.AnchoredSystemPath
+ packageMode PackageType
+ }{
+ // Scenario 0
+ {
+ name: "turbo.json at current dir, no package.json",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ {
+ name: "turbo.json at parent dir, no package.json",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ // This is "no inference"
+ rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ packageMode: Multi,
+ },
+ // Scenario 1A
+ {
+ name: "turbo.json at current dir, has package.json, has workspaces key",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ {
+ name: "turbo.json at parent dir, has package.json, has workspaces key",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ {
+ name: "turbo.json at parent dir, has package.json, has pnpm workspaces",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("pnpm-workspace.yaml").ToSystemPath(),
+ content: []byte("packages:\n - docs"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ // Scenario 1A aware of the weird thing we do for packages.
+ {
+ name: "turbo.json at current dir, has package.json, has packages key",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"packages\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Single,
+ },
+ {
+ name: "turbo.json at parent dir, has package.json, has packages key",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"packages\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Single,
+ },
+ // Scenario 1A aware of the the weird thing we do for packages when both methods of specification exist.
+ {
+ name: "turbo.json at current dir, has package.json, has workspace and packages key",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"clobbered\" ], \"packages\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ {
+ name: "turbo.json at parent dir, has package.json, has workspace and packages key",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"clobbered\" ], \"packages\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ // Scenario 1B
+ {
+ name: "turbo.json at current dir, has package.json, no workspaces",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Single,
+ },
+ {
+ name: "turbo.json at parent dir, has package.json, no workspaces",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Single,
+ },
+ {
+ name: "turbo.json at parent dir, has package.json, no workspaces, includes pnpm",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {path: turbopath.AnchoredUnixPath("turbo.json").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("pnpm-workspace.yaml").ToSystemPath(),
+ content: []byte(""),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Single,
+ },
+ // Scenario 2A
+ {
+ name: "no turbo.json, no package.json at current",
+ fs: []file{},
+ executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ {
+ name: "no turbo.json, no package.json at parent",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ packageMode: Multi,
+ },
+ // Scenario 2B
+ {
+ name: "no turbo.json, has package.json with workspaces at current",
+ fs: []file{
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("").ToSystemPath(),
+ packageMode: Multi,
+ },
+ {
+ name: "no turbo.json, has package.json with workspaces at parent",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"exists\" ] }"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ packageMode: Multi,
+ },
+ {
+ name: "no turbo.json, has package.json with pnpm workspaces at parent",
+ fs: []file{
+ {path: turbopath.AnchoredUnixPath("execution/path/subdir/.file").ToSystemPath()},
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"exists\" ] }"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("pnpm-workspace.yaml").ToSystemPath(),
+ content: []byte("packages:\n - docs"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("execution/path/subdir").ToSystemPath(),
+ packageMode: Multi,
+ },
+ // Scenario 3A
+ {
+ name: "no turbo.json, lots of package.json files but no workspaces",
+ fs: []file{
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/two/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/two/three/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(),
+ packageMode: Single,
+ },
+ // Scenario 3BI
+ {
+ name: "no turbo.json, lots of package.json files, and a workspace at the root that matches execution directory",
+ fs: []file{
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"one/two/three\" ] }"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/two/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/two/three/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(),
+ packageMode: Multi,
+ },
+ // Scenario 3BII
+ {
+ name: "no turbo.json, lots of package.json files, and a workspace at the root that matches execution directory",
+ fs: []file{
+ {
+ path: turbopath.AnchoredUnixPath("package.json").ToSystemPath(),
+ content: []byte("{ \"workspaces\": [ \"does-not-exist\" ] }"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/two/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ {
+ path: turbopath.AnchoredUnixPath("one/two/three/package.json").ToSystemPath(),
+ content: []byte("{}"),
+ },
+ },
+ executionDirectory: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(),
+ rootPath: turbopath.AnchoredUnixPath("one/two/three").ToSystemPath(),
+ packageMode: Single,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ fsRoot := turbopath.AbsoluteSystemPath(t.TempDir())
+ for _, file := range tt.fs {
+ path := file.path.RestoreAnchor(fsRoot)
+ assert.NilError(t, path.Dir().MkdirAll(0777))
+ assert.NilError(t, path.WriteFile(file.content, 0777))
+ }
+
+ turboRoot, packageMode := InferRoot(tt.executionDirectory.RestoreAnchor(fsRoot))
+ if !reflect.DeepEqual(turboRoot, tt.rootPath.RestoreAnchor(fsRoot)) {
+ t.Errorf("InferRoot() turboRoot = %v, want %v", turboRoot, tt.rootPath.RestoreAnchor(fsRoot))
+ }
+ if packageMode != tt.packageMode {
+ t.Errorf("InferRoot() packageMode = %v, want %v", packageMode, tt.packageMode)
+ }
+ })
+ }
+}