Skip to content

Fix loading projects on network drives #996

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 15 additions & 5 deletions packages/tailwindcss-language-server/src/project-locator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as path from 'node:path'
import * as fs from 'node:fs/promises'
import glob from 'fast-glob'
import picomatch from 'picomatch'
import normalizePath from 'normalize-path'
import type { Settings } from '@tailwindcss/language-service/src/util/state'
import { CONFIG_GLOB, CSS_GLOB } from './lib/constants'
import { readCssFile } from './util/css'
Expand All @@ -14,9 +13,8 @@ import { CacheMap } from './cache-map'
import { getPackageRoot } from './util/get-package-root'
import resolveFrom from './util/resolveFrom'
import { type Feature, supportedFeatures } from '@tailwindcss/language-service/src/features'
import { pathToFileURL } from 'node:url'
import { resolveCssImports } from './resolve-css-imports'
import { normalizeDriveLetter } from './utils'
import { normalizeDriveLetter, normalizePath, pathToFileURL } from './utils'

export interface ProjectConfig {
/** The folder that contains the project */
Expand Down Expand Up @@ -244,8 +242,20 @@ export class ProjectLocator {
concurrency: Math.max(os.cpus().length, 1),
})

// Resolve symlinks for all found files
files = await Promise.all(files.map(async (file) => normalizePath(await fs.realpath(file))))
files = await Promise.all(
files.map(async (file) => {
// Resolve symlinks for all found files
let actualPath = await fs.realpath(file)

// Ignore network paths on Windows. Resolving relative paths on a
// netshare throws in `enhanced-resolve` :/
if (actualPath.startsWith('\\') && process.platform === 'win32') {
return normalizePath(file)
}

return normalizePath(actualPath)
}),
)

// Deduplicate the list of files and sort them for deterministic results
// across environments
Expand Down
4 changes: 2 additions & 2 deletions packages/tailwindcss-language-server/src/projects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import { FileChangeType } from 'vscode-languageserver/node'
import type { TextDocument } from 'vscode-languageserver-textdocument'
import { URI } from 'vscode-uri'
import { showError, SilentError } from './util/error'
import normalizePath from 'normalize-path'
import * as path from 'path'
import * as fs from 'fs'
import findUp from 'find-up'
Expand Down Expand Up @@ -70,14 +69,15 @@ import {
clearRequireCache,
withFallback,
isObject,
pathToFileURL,
changeAffectsFile,
normalizePath,
} from './utils'
import type { DocumentService } from './documents'
import type { ProjectConfig } from './project-locator'
import { supportedFeatures } from '@tailwindcss/language-service/src/features'
import { loadDesignSystem } from './util/v4'
import { readCssFile } from './util/css'
import { pathToFileURL } from 'url'

const colorNames = Object.keys(namedColors)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// https://github.com/tailwindlabs/tailwindcss/blob/bac5ecf0040aa9a788d1b22d706506146ee831ff/src/lib/getModuleDependencies.js
import fs from 'fs'
import path from 'path'
import normalizePath from 'normalize-path'
import { normalizePath } from '../utils'

let jsExtensions = ['.js', '.cjs', '.mjs']

Expand Down
10 changes: 10 additions & 0 deletions packages/tailwindcss-language-server/src/util/resolveFrom.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { equal } from '@tailwindcss/language-service/src/util/array'
import * as path from 'node:path'
import { createResolver } from './resolve'

let pnpApi: any
Expand All @@ -16,8 +17,17 @@ export function setPnpApi(newPnpApi: any): void {
}

export default function resolveFrom(from?: string, id?: string): string {
// Network share path on Windows
if (id.startsWith('\\\\')) return id

// Normalized network share path on Windows
if (id.startsWith('//') && path.sep === '\\') return id

// Normalized network share path on Windows
if (from.startsWith('//') && path.sep === '\\') {
from = '\\\\' + from.slice(2)
}

let newExtensions = Object.keys(require.extensions)
if (!equal(newExtensions, extensions)) {
extensions = newExtensions
Expand Down
34 changes: 34 additions & 0 deletions packages/tailwindcss-language-server/src/utils.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import Module from 'node:module'
import path from 'node:path'
import { URI } from 'vscode-uri'
import normalizePathBase from 'normalize-path'
import { pathToFileURL as pathToFileURLBase } from 'node:url'

export function withoutLogs<T>(getter: () => T): T {
let fns = {
Expand Down Expand Up @@ -89,3 +92,34 @@ export function changeAffectsFile(change: string, files: string[]): boolean {
}
return false
}

export function normalizePath(originalPath: string) {
let normalized = normalizePathBase(originalPath)

// This is Windows network share but the normalize path had one of the leading
// slashes stripped so we need to add it back
if (
originalPath.startsWith('\\\\') &&
normalized.startsWith('/') &&
!normalized.startsWith('//')
) {
return `/${normalized}`
}

return normalized
}

export function pathToFileURL(filepath: string) {
try {
return pathToFileURLBase(filepath)
} catch (err) {
if (process.platform !== 'win32') throw err

// If `pathToFileURL` failsed on windows it's probably because the path was
// a windows network share path and there were mixed slashes.
// Fix the path and try again.
filepath = URI.file(filepath).fsPath

return pathToFileURLBase(filepath)
}
}
2 changes: 1 addition & 1 deletion packages/vscode-tailwindcss/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

## Prerelease

- Nothing yet!
- Fix loading projects on Windows network drives ([#996](https://github.com/tailwindlabs/tailwindcss-intellisense/pull/996))

## 0.12.1

Expand Down