Skip to content

Fix build:all output on Windows #8089

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
Mar 14, 2025
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

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion src/overrides/assets/javascripts/iconsearch_index.json

This file was deleted.

3 changes: 2 additions & 1 deletion tools/build/_/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import * as chokidar from "chokidar"
import * as fs from "fs/promises"
import * as path from "path"
import {
EMPTY,
Observable,
Expand Down Expand Up @@ -120,7 +121,7 @@ export function resolve(

/* Build overrides */
!process.argv.includes("--all")
? filter(file => !file.startsWith(".overrides/"))
? filter(file => !file.startsWith(`.overrides${path.sep}`))
: identity,
)
}
Expand Down
94 changes: 85 additions & 9 deletions tools/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import {
concat,
defer,
from,
identity,
map,
merge,
mergeMap,
Expand Down Expand Up @@ -112,6 +113,75 @@ function minsvg(data: string): string {
return result.data
}

/**
* Return a path with POSIX style separators
*
* The default function assumes UNIX system, so it just returns the path.
*
* @param p - string path
* @returns String path
*/
let assurePosixSep = function (p: string): string {
return p
};

/**
* Return a path with POSIX style separators
*
* The Windows variant of this function replaces the separator with regex.
*
* @param p - string path
* @returns String path
*/
function assurePosixSepWin(p: string): string {
return p.replace(winSepRegex, path.posix.sep)
};

const winSepRegex = new RegExp(`\\${path.win32.sep}`, "g");

if (path.sep === path.win32.sep) {
assurePosixSep = assurePosixSepWin;
}

/**
* Compare two path strings to decide on the order
*
* On Windows the default order of paths containing `_` from the resolve function
* is different than on macOS. This function restores the order to the usual.
* Implementation adapted based on https://t.ly/VJp78
*
* Note: The paths should have no extension like .svg, just the name. Otherwise
* it won't check the compare.startsWith(reference) properly.
*
* @param reference Left string to compare
* @param compare Right string to compare against
* @returns Number for the sort function to define the order
*/
function sortOrderForWindows(reference: string, compare: string): number {
reference = reference.toLowerCase();
compare = compare.toLowerCase();

const length = Math.min(reference.length, compare.length);

for (let i = 0; i < length; i++) {
const leftChar = reference[i];
const rightChar = compare[i];

if (leftChar !== rightChar)
return customAlphabet.indexOf(leftChar) - customAlphabet.indexOf(rightChar);
}

if (reference.length !== compare.length) {
if (compare.startsWith(reference) && compare[reference.length] === "-")
return 1;
return reference.length - compare.length;
}

return 0;
}

const customAlphabet: string = "_,-./0123456789abcdefghijklmnopqrstuvwxyz";

/* ----------------------------------------------------------------------------
* Tasks
* ------------------------------------------------------------------------- */
Expand Down Expand Up @@ -187,7 +257,7 @@ const sources$ = copyAll("**/*.py", {
const stylesheets$ = resolve("**/[!_]*.scss", { cwd: "src" })
.pipe(
mergeMap(file => zip(
of(ext(file, ".css").replace(/(overrides|templates)\//, "")),
of(ext(file, ".css").replace(new RegExp(`(overrides|templates)\\${path.sep}`), "")),
transformStyle({
from: `src/${file}`,
to: ext(`${base}/${file}`, ".css")
Expand All @@ -199,7 +269,7 @@ const stylesheets$ = resolve("**/[!_]*.scss", { cwd: "src" })
const javascripts$ = resolve("**/{custom,bundle,search}.ts", { cwd: "src" })
.pipe(
mergeMap(file => zip(
of(ext(file, ".js").replace(/(overrides|templates)\//, "")),
of(ext(file, ".js").replace(new RegExp(`(overrides|templates)\\${path.sep}`), "")),
transformScript({
from: `src/${file}`,
to: ext(`${base}/${file}`, ".js")
Expand Down Expand Up @@ -229,10 +299,10 @@ const manifest$ = merge(
.pipe(
scan((prev, mapping) => (
mapping.reduce((next, [key, value]) => (
next.set(key, value.replace(
new RegExp(`${base}\\/(overrides|templates)\\/`),
next.set(assurePosixSep(key), assurePosixSep(value.replace(
new RegExp(`${base}\\/(overrides|templates)\\${path.sep}`),
""
))
)))
), prev)
), new Map<string, string>()),
)
Expand Down Expand Up @@ -291,9 +361,15 @@ const icons$ = defer(() => resolve("**/*.svg", {
}))
.pipe(
reduce((index, file) => index.set(
file.replace(/\.svg$/, "").replace(/\//g, "-"),
file
), new Map<string, string>())
file.replace(/\.svg$/, "").replace(new RegExp(`\\${path.sep}`, "g"), "-"),
assurePosixSep(file)
), new Map<string, string>()),
// The icons are stored in the index file, and the output needs to be OS
// agnostic. Some icons contain the `_` character, which has different order
// in the glob output on Windows.
(path.sep === path.win32.sep) ? map(icons => new Map(
[...icons].sort((a, b) => sortOrderForWindows(a[0], b[0]))
)) : identity
)

/* Compute emoji mappings (based on Twemoji) */
Expand Down Expand Up @@ -372,7 +448,7 @@ const schema$ = merge(
"reference/icons-emojis/#search"
].join("/"),
"type": "string",
"enum": icons.map(icon => icon.replace(".svg", ""))
"enum": icons.map(icon => assurePosixSep(icon.replace(".svg", "")))
})),
switchMap(data => write(
"docs/schema/assets/icons.json",
Expand Down
3 changes: 2 additions & 1 deletion tools/build/transform/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ interface TransformOptions {
/**
* Base directory for source map resolution
*/
const root = new RegExp(`file://${path.resolve(".")}/`, "g")
const currentPath = path.resolve(".").replace(new RegExp(`\\${path.win32.sep}`, "g"), path.posix.sep)
const root = path.sep === path.posix.sep ? new RegExp(`file://${currentPath}/`, "g") : new RegExp(`file:///${currentPath}/`, "g")

/* ----------------------------------------------------------------------------
* Helper functions
Expand Down