| 576 | 576 | | return Ok(None); |
| 577 | 577 | | }; |
| 578 | 578 | | let path = dir.join(".wrangler/deploy").join(path); |
| 579 | | − | let path = path.canonicalize().unwrap_or(path); |
| 579 | + | let path = canonical(&path).unwrap_or(path); |
| 580 | 580 | | let text = std::fs::read_to_string(&path).with_context(|| format!("could not read {}", path.display()))?; |
| 581 | 581 | | let config = serde_json::from_str(&strip_jsonc(&text)).with_context(|| format!("could not read {}", path.display()))?; |
| 582 | 582 | | Ok(Some((config, path.parent().map_or_else(|| dir.to_path_buf(), Path::to_path_buf)))) |
| 583 | 583 | | } |
| 584 | 584 | | |
| 585 | + | /// The path, resolved, as a plain path. On Windows, `canonicalize` gives a |
| 586 | + | /// verbatim one (`\\?\C:\…`), in which `/` and `..` are not read as |
| 587 | + | /// separators or as the folder above: a config's `"directory": "../client"` |
| 588 | + | /// joined to it would name no folder. A drive path loses the prefix; a |
| 589 | + | /// network path keeps it, as it cannot do without. |
| 590 | + | fn canonical(path: &Path) -> std::io::Result<PathBuf> { |
| 591 | + | let path = path.canonicalize()?; |
| 592 | + | #[cfg(windows)] |
| 593 | + | { |
| 594 | + | let text = path.to_string_lossy(); |
| 595 | + | if let Some(rest) = text.strip_prefix(r"\\?\") { |
| 596 | + | if !rest.starts_with(r"UNC\") { |
| 597 | + | return Ok(PathBuf::from(rest)); |
| 598 | + | } |
| 599 | + | } |
| 600 | + | } |
| 601 | + | Ok(path) |
| 602 | + | } |
| 603 | + | |
| 585 | 604 | | /// The entry of the Worker a framework's adapter wrote, once it has built: |
| 586 | 605 | | /// the file, or a directory's `index.js`. |
| 587 | 606 | | fn adapter_entry(dir: &Path, adapter: &Adapter) -> Option<PathBuf> { |
| ⋯ |
| 2148 | 2167 | | ); |
| 2149 | 2168 | | let (config, base) = redirected_config(&dir).unwrap().unwrap(); |
| 2150 | 2169 | | assert_eq!(config.main.as_deref(), Some("index.js")); |
| 2151 | | − | assert_eq!(base, dir.join("dist/app").canonicalize().unwrap()); |
| 2170 | + | assert_eq!(base, canonical(&dir.join("dist/app")).unwrap()); |
| 2152 | 2171 | | assert!(base.join(config.assets.unwrap().directory.unwrap()).ends_with("dist/app/../client")); |
| 2153 | 2172 | | assert!(redirected_config(&project("not-redirected", &[])).unwrap().is_none()); |
| 2154 | 2173 | | } |