Skip to content

Commit f378625

Browse files
Fix integration tests on Windows (#14824)
This PR fixes Windows related path issues after merging #14820 --------- Co-authored-by: Jordan Pittman <jordan@cryptica.me>
1 parent e52bf2e commit f378625

File tree

11 files changed

+153
-35
lines changed

11 files changed

+153
-35
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# `@tailwindcss/oxide-win32-arm64-msvc`
2+
3+
This is the **arm64-pc-windows-msvc** binary for `@tailwindcss/oxide`
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "@tailwindcss/oxide-win32-arm64-msvc",
3+
"version": "4.0.0-alpha.30",
4+
"repository": {
5+
"type": "git",
6+
"url": "git+https://github.com/tailwindlabs/tailwindcss.git",
7+
"directory": "crates/node/npm/win32-arm64-msvc"
8+
},
9+
"os": [
10+
"win32"
11+
],
12+
"cpu": [
13+
"arm64"
14+
],
15+
"main": "tailwindcss-oxide.win32-arm64-msvc.node",
16+
"files": [
17+
"tailwindcss-oxide.win32-arm64-msvc.node"
18+
],
19+
"publishConfig": {
20+
"provenance": true,
21+
"access": "public"
22+
},
23+
"license": "MIT",
24+
"engines": {
25+
"node": ">= 10"
26+
}
27+
}

crates/node/package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020
"armv7-unknown-linux-gnueabihf",
2121
"x86_64-unknown-linux-musl",
2222
"x86_64-unknown-freebsd",
23-
"i686-pc-windows-msvc"
23+
"i686-pc-windows-msvc",
24+
"aarch64-pc-windows-msvc"
2425
]
2526
}
2627
},
@@ -56,6 +57,7 @@
5657
"@tailwindcss/oxide-linux-arm64-musl": "workspace:*",
5758
"@tailwindcss/oxide-linux-x64-gnu": "workspace:*",
5859
"@tailwindcss/oxide-linux-x64-musl": "workspace:*",
59-
"@tailwindcss/oxide-win32-x64-msvc": "workspace:*"
60+
"@tailwindcss/oxide-win32-x64-msvc": "workspace:*",
61+
"@tailwindcss/oxide-win32-arm64-msvc": "workspace:*"
6062
}
6163
}

crates/oxide/src/glob.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -237,15 +237,18 @@ mod tests {
237237

238238
let optimized_sources = optimize_patterns(&sources);
239239

240-
let parent_dir = format!("{}", fs::canonicalize(base).unwrap().display());
240+
let parent_dir =
241+
format!("{}{}", dunce::canonicalize(base).unwrap().display(), "/").replace('\\', "/");
241242

242243
// Remove the temporary directory from the base
243244
optimized_sources
244245
.into_iter()
245-
.map(|source| GlobEntry {
246-
// Normalize paths to use unix style separators
247-
base: source.base.replace(&parent_dir, "").replace('\\', "/"),
248-
pattern: source.pattern,
246+
.map(|source| {
247+
GlobEntry {
248+
// Normalize paths to use unix style separators
249+
base: source.base.replace('\\', "/").replace(&parent_dir, "/"),
250+
pattern: source.pattern,
251+
}
249252
})
250253
.collect()
251254
}

crates/oxide/src/lib.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use bstr::ByteSlice;
77
use fxhash::{FxHashMap, FxHashSet};
88
use glob::optimize_patterns;
99
use glob_match::glob_match;
10+
use paths::Path;
1011
use rayon::prelude::*;
1112
use std::fs;
1213
use std::path::PathBuf;
@@ -18,6 +19,7 @@ pub mod cursor;
1819
pub mod fast_skip;
1920
pub mod glob;
2021
pub mod parser;
22+
pub mod paths;
2123
pub mod scanner;
2224

2325
static SHOULD_TRACE: sync::LazyLock<bool> = sync::LazyLock::new(
@@ -151,7 +153,8 @@ impl Scanner {
151153

152154
self.files
153155
.iter()
154-
.map(|x| x.to_string_lossy().into())
156+
.filter_map(|x| Path::from(x.clone()).canonicalize().ok())
157+
.map(|x| x.to_string())
155158
.collect()
156159
}
157160

@@ -257,9 +260,18 @@ impl Scanner {
257260
false
258261
});
259262

263+
fn join_paths(a: &str, b: &str) -> PathBuf {
264+
let mut tmp = a.to_owned();
265+
266+
tmp += "/";
267+
tmp += b.trim_end_matches("**/*").trim_end_matches('/');
268+
269+
PathBuf::from(&tmp)
270+
}
271+
260272
for path in auto_sources
261273
.iter()
262-
.map(|source| PathBuf::from(&source.base).join(source.pattern.trim_end_matches("**/*")))
274+
.map(|source| join_paths(&source.base, &source.pattern))
263275
{
264276
// Insert a glob for the base path, so we can see new files/folders in the directory itself.
265277
self.globs.push(GlobEntry {
@@ -292,7 +304,8 @@ impl Scanner {
292304
// match as well.
293305
//
294306
// Instead we combine the base and the pattern as a single glob pattern.
295-
let mut full_pattern = source.base.clone();
307+
let mut full_pattern = source.base.clone().replace('\\', "/");
308+
296309
if !source.pattern.is_empty() {
297310
full_pattern.push('/');
298311
full_pattern.push_str(&source.pattern);
@@ -314,7 +327,9 @@ impl Scanner {
314327
continue;
315328
};
316329

317-
if glob_match(&full_pattern, file_path_str) {
330+
let file_path_str = file_path_str.replace('\\', "/");
331+
332+
if glob_match(&full_pattern, &file_path_str) {
318333
self.files.push(file_path);
319334
}
320335
}

crates/oxide/src/paths.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
use std::fmt::Display;
2+
use std::io;
3+
use std::path;
4+
5+
#[derive(Clone)]
6+
pub struct Path {
7+
inner: path::PathBuf,
8+
}
9+
10+
impl From<path::PathBuf> for Path {
11+
fn from(value: path::PathBuf) -> Self {
12+
Self { inner: value }
13+
}
14+
}
15+
16+
impl From<String> for Path {
17+
fn from(value: String) -> Self {
18+
Self {
19+
inner: value.into(),
20+
}
21+
}
22+
}
23+
24+
impl From<&str> for Path {
25+
fn from(value: &str) -> Self {
26+
Self {
27+
inner: value.into(),
28+
}
29+
}
30+
}
31+
32+
impl Display for Path {
33+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34+
write!(
35+
f,
36+
"{}",
37+
format!("{}", self.inner.display()).replace('\\', "/")
38+
)
39+
}
40+
}
41+
42+
impl Path {
43+
pub fn trim_prefix(&self, prefix: String) -> Self {
44+
let prefix = prefix.replace('\\', "/");
45+
let my_path = self.to_string();
46+
47+
if let Some(str) = my_path.strip_prefix(&prefix) {
48+
return str.into();
49+
}
50+
51+
my_path.into()
52+
}
53+
54+
pub fn join(&self, component: &str) -> Self {
55+
if component.is_empty() {
56+
return self.clone();
57+
}
58+
59+
self.inner.join(component).into()
60+
}
61+
62+
pub fn canonicalize(&self) -> io::Result<Self> {
63+
Ok(dunce::canonicalize(&self.inner)?.into())
64+
}
65+
}

crates/oxide/tests/scanner.rs

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ mod scanner {
3131
}
3232
}
3333

34-
let base = format!("{}", dir.display());
34+
let base = format!("{}", dir.display()).replace('\\', "/");
3535

3636
// Resolve all content paths for the (temporary) current working directory
3737
let mut sources: Vec<GlobEntry> = globs
@@ -51,31 +51,20 @@ mod scanner {
5151

5252
let candidates = scanner.scan();
5353

54-
let mut paths: Vec<_> = scanner
55-
.get_files()
56-
.into_iter()
57-
.map(|x| x.replace(&format!("{}{}", &base, path::MAIN_SEPARATOR), ""))
58-
.collect();
54+
let mut paths: Vec<_> = scanner.get_files();
5955

6056
for glob in scanner.get_globs() {
61-
paths.push(format!(
62-
"{}{}{}",
63-
glob.base,
64-
path::MAIN_SEPARATOR,
65-
glob.pattern
66-
));
57+
paths.push(format!("{}{}{}", glob.base, "/", glob.pattern));
6758
}
6859

69-
let parent_dir = format!(
70-
"{}{}",
71-
fs::canonicalize(&base).unwrap().display(),
72-
path::MAIN_SEPARATOR
73-
);
60+
let parent_dir =
61+
format!("{}{}", dunce::canonicalize(&base).unwrap().display(), "/").replace('\\', "/");
7462

7563
paths = paths
7664
.into_iter()
7765
.map(|x| {
78-
x.replace(&parent_dir, "").replace('\\', "/") // Normalize paths to use unix style separators
66+
// Normalize paths to use unix style separators
67+
x.replace('\\', "/").replace(&parent_dir, "")
7968
})
8069
.collect();
8170

packages/@tailwindcss-standalone/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"@parcel/watcher-linux-x64-musl": "^2.4.2-alpha.0",
4141
"@parcel/watcher-win32-x64": "^2.4.2-alpha.0",
4242
"@types/bun": "^1.1.11",
43-
"bun": "^1.1.29",
43+
"bun": "1.1.29",
4444
"lightningcss-darwin-arm64": "^1.25.1",
4545
"lightningcss-darwin-x64": "^1.25.1",
4646
"lightningcss-linux-arm64-gnu": "^1.25.1",

packages/@tailwindcss-vite/src/index.ts

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ class Root {
431431
let root = this.compiler.root
432432

433433
if (root !== 'none' && root !== null) {
434-
let basePath = path.posix.resolve(root.base, root.pattern)
434+
let basePath = normalizePath(path.resolve(root.base, root.pattern))
435435

436436
let isDir = await fs.stat(basePath).then(
437437
(stats) => stats.isDirectory(),
@@ -463,14 +463,22 @@ class Root {
463463
if (!this.compiler) return new Set()
464464
if (this.compiler.root === 'none') return new Set()
465465

466+
const HAS_DRIVE_LETTER = /^[A-Z]:/
467+
466468
let shouldIncludeCandidatesFrom = (id: string) => {
467469
if (this.basePath === null) return true
468470

469-
// This a virtual module that's not on the file system
470-
// TODO: What should we do here?
471+
if (id.startsWith(this.basePath)) return true
472+
473+
// This is a windows absolute path that doesn't match so return false
474+
if (HAS_DRIVE_LETTER.test(id)) return false
475+
476+
// We've got a path that's not absolute and not on Windows
477+
// TODO: this is probably a virtual module -- not sure if we need to scan it
471478
if (!id.startsWith('/')) return true
472479

473-
return id.startsWith(this.basePath)
480+
// This is an absolute path on POSIX and it does not match
481+
return false
474482
}
475483

476484
let shared = new Set<string>()

pnpm-lock.yaml

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)