diff --git a/tsc/cmd/tsc/lsp.go b/tsc/cmd/tsc/lsp.go index b294ad5688416..3bb3affd2b160 100644 --- a/tsc/cmd/tsc/lsp.go +++ b/tsc/cmd/tsc/lsp.go @@ -57,7 +57,7 @@ func runLSP(args []string) int { Cwd: cwd, FS: fs, DefaultLibraryPath: defaultLibraryPath, - TypingsLocation: tspath.ToRootedDirectoryPath(typingsLocation, cwd), + TypingsLocation: typingsLocation, NpmInstall: func(ctx context.Context, cwd string, args []string) ([]byte, error) { cmd := exec.CommandContext(ctx, "npm", args...) cmd.Dir = cwd diff --git a/tsc/internal/lsp/replay_test.go b/tsc/internal/lsp/replay_test.go index d0b40f33042b6..55264326a44bf 100644 --- a/tsc/internal/lsp/replay_test.go +++ b/tsc/internal/lsp/replay_test.go @@ -58,7 +58,7 @@ func TestReplay(t *testing.T) { Cwd: cwd, FS: fs, DefaultLibraryPath: defaultLibraryPath, - TypingsLocation: tspath.ToRootedDirectoryPath(typingsLocation, cwd), + TypingsLocation: typingsLocation, NpmInstall: func(ctx context.Context, cwd string, args []string) ([]byte, error) { cmd := exec.CommandContext(ctx, "npm", args...) cmd.Dir = cwd diff --git a/tsc/internal/project/ata/ata_test.go b/tsc/internal/project/ata/ata_test.go index 258788185c9c0..60021e4573adc 100644 --- a/tsc/internal/project/ata/ata_test.go +++ b/tsc/internal/project/ata/ata_test.go @@ -10,6 +10,7 @@ import ( "github.com/microsoft/TypeScript/tsc/internal/lsp/lsproto" "github.com/microsoft/TypeScript/tsc/internal/project" "github.com/microsoft/TypeScript/tsc/internal/testutil/projecttestutil" + "github.com/microsoft/TypeScript/tsc/internal/tspath" "gotest.tools/v3/assert" ) @@ -19,6 +20,36 @@ func TestATA(t *testing.T) { t.Skip("bundled files are not embedded") } + t.Run("no typings cache disables acquisition", func(t *testing.T) { + t.Parallel() + + files := map[string]any{ + "/user/username/projects/project/app.js": `const $ = require("jquery");`, + "/user/username/projects/project/jsconfig.json": `{ + "typeAcquisition": { "enable": true } + }`, + } + session, utils := projecttestutil.SetupWithOptionsAndTypingsInstaller(files, &project.SessionOptions{ + CurrentDirectory: tspath.RootedDirectoryPathFromNormalized("/"), + DefaultLibraryPath: bundled.LibPath(), + WatchEnabled: true, + }, &projecttestutil.TypingsInstallerOptions{ + PackageToFile: map[string]string{ + "jquery": `export const x: number;`, + }, + }) + + uri := lsproto.DocumentUri("file:///user/username/projects/project/app.js") + session.DidOpenFile(context.Background(), uri, 1, files["/user/username/projects/project/app.js"].(string), lsproto.LanguageKindJavaScript) + session.WaitForBackgroundTasks() + + ls, err := session.GetLanguageService(context.Background(), uri) + assert.NilError(t, err) + assert.Assert(t, ls.GetProgram().GetSourceFile("/user/username/projects/project/app.js") != nil) + assert.Equal(t, len(utils.NpmExecutor().NpmInstallCalls()), 0) + assert.Assert(t, !session.FS().FileExists(projecttestutil.TestTypingsDirectory.ResolveFile("package.json"))) + }) + t.Run("local module should not be picked up", func(t *testing.T) { t.Parallel() files := map[string]any{ diff --git a/tsc/internal/vfs/osvfs/os.go b/tsc/internal/vfs/osvfs/os.go index bde446fbb56f9..6ad2eb1837f29 100644 --- a/tsc/internal/vfs/osvfs/os.go +++ b/tsc/internal/vfs/osvfs/os.go @@ -228,10 +228,14 @@ func (vfs *osFS) Chtimes(path tspath.RootedPath, aTime time.Time, mTime time.Tim return os.Chtimes(path.AsString(), aTime, mTime) } -func GetGlobalTypingsCacheLocation() string { +func GetGlobalTypingsCacheLocation() tspath.RootedDirectoryPath { cacheDir, err := os.UserCacheDir() if err != nil { - cacheDir = os.TempDir() + return "" + } + cachePath, ok := tspath.TryRootedPathFromAbsolute(cacheDir) + if !ok { + return "" } var subdir string @@ -240,5 +244,5 @@ func GetGlobalTypingsCacheLocation() string { } else { subdir = "typescript" } - return tspath.CombinePaths(cacheDir, subdir, core.VersionMajorMinor()) + return tspath.RootedDirectoryPathFromPath(cachePath).ResolveDirectory(subdir).ResolveDirectory(core.VersionMajorMinor()) } diff --git a/tsc/internal/vfs/osvfs/os_test.go b/tsc/internal/vfs/osvfs/os_test.go index 69b53619f67a3..804b49722ff08 100644 --- a/tsc/internal/vfs/osvfs/os_test.go +++ b/tsc/internal/vfs/osvfs/os_test.go @@ -8,6 +8,7 @@ import ( "testing" "time" + "github.com/microsoft/TypeScript/tsc/internal/core" "github.com/microsoft/TypeScript/tsc/internal/nativepath" "github.com/microsoft/TypeScript/tsc/internal/repo" "github.com/microsoft/TypeScript/tsc/internal/tspath" @@ -15,6 +16,48 @@ import ( "gotest.tools/v3/assert" ) +func TestGetGlobalTypingsCacheLocation(t *testing.T) { + t.Run("user cache", func(t *testing.T) { + cacheRoot := t.TempDir() + t.Setenv("HOME", cacheRoot) + t.Setenv("home", cacheRoot) + t.Setenv("LocalAppData", cacheRoot) + t.Setenv("XDG_CACHE_HOME", cacheRoot) + cacheDir, err := os.UserCacheDir() + assert.NilError(t, err) + + subdir := "typescript" + if runtime.GOOS == "windows" { + subdir = "Microsoft/TypeScript" + } + assert.Equal(t, osvfs.GetGlobalTypingsCacheLocation(), tspath.RootedDirectoryPathFromAbsolute(tspath.CombinePaths(cacheDir, subdir, core.VersionMajorMinor()))) + }) + + t.Run("missing user cache", func(t *testing.T) { + for _, name := range []string{"HOME", "home", "LocalAppData", "XDG_CACHE_HOME"} { + t.Setenv(name, "") + } + assert.Equal(t, osvfs.GetGlobalTypingsCacheLocation(), tspath.RootedDirectoryPath("")) + }) + + t.Run("relative XDG cache", func(t *testing.T) { + switch runtime.GOOS { + case "windows", "darwin", "ios", "plan9": + t.Skip("XDG_CACHE_HOME is not used on this platform") + } + t.Setenv("XDG_CACHE_HOME", "relative") + assert.Equal(t, osvfs.GetGlobalTypingsCacheLocation(), tspath.RootedDirectoryPath("")) + }) + + t.Run("relative user cache", func(t *testing.T) { + t.Setenv("XDG_CACHE_HOME", "") + for _, name := range []string{"HOME", "home", "LocalAppData"} { + t.Setenv(name, "relative-home") + } + assert.Equal(t, osvfs.GetGlobalTypingsCacheLocation(), tspath.RootedDirectoryPath("")) + }) +} + func TestOS(t *testing.T) { t.Parallel()