Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
037609e
feat(fs): Enhance API for incremental build, add tracking readers/wri…
RandomByte Nov 18, 2025
5a4f49b
feat(server): Use incremental build in server
RandomByte Nov 18, 2025
506a151
feat(builder): Adapt tasks for incremental build
RandomByte Nov 18, 2025
2441ca6
refactor(project): Align getReader API internals with ComponentProjects
RandomByte Nov 18, 2025
71bd73f
refactor(project): Refactor specification-internal workspace handling
RandomByte Nov 18, 2025
928df02
refactor(project): Implement basic incremental build functionality
RandomByte Nov 18, 2025
f31f7f3
refactor(cli): Use cache in ui5 build
RandomByte Nov 18, 2025
fdcdd58
refactor(project): Use cacache
RandomByte Nov 24, 2025
78a11f1
refactor(project): Add cache manager
RandomByte Nov 28, 2025
b79302d
refactor(fs): Refactor Resource internals
RandomByte Nov 27, 2025
3c4d177
refactor(fs): Provide createBuffer factory in FileSystem adapter
RandomByte Dec 1, 2025
833dc93
refactor(project): Refactor cache classes
RandomByte Dec 1, 2025
fd178e5
refactor(fs): Add Proxy reader
RandomByte Dec 4, 2025
0eeeeee
refactor(project): API refactoring
RandomByte Dec 8, 2025
d95116d
refactor(builder): Rename task param 'buildCache' to 'cacheUtil'
RandomByte Dec 10, 2025
aaa3d72
refactor(project): Cleanup
RandomByte Dec 10, 2025
666d808
refactor(project): Move resource comparison to util
RandomByte Dec 12, 2025
b3edae7
refactor(project): Refactor stage handling
RandomByte Dec 16, 2025
cd26bba
refactor(project): Fix cache handling
RandomByte Dec 16, 2025
ee51c11
refactor(fs): Remove contentAccess mutex timeout from Resource
RandomByte Dec 16, 2025
3b008ee
refactor(project): Cleanup obsolete code/comments
RandomByte Dec 16, 2025
d730316
refactor(server): Cleanup obsolete code
RandomByte Dec 16, 2025
25f84e3
refactor(project): Rename watch handler events
RandomByte Dec 16, 2025
b6c69ad
refactor: Fix linting issues
matz3 Dec 17, 2025
bfe9463
test(fs): Adjust getIntegrity tests
matz3 Dec 17, 2025
4cee48f
refactor: Integrity handling
matz3 Dec 17, 2025
af0ac96
test(fs): Adjust getIntegrity tests again
matz3 Dec 17, 2025
d030e83
refactor: Consider npm-shrinkwrap.json
matz3 Dec 17, 2025
d7c1e7b
refactor: Rename Tracker => MonitoredReader
RandomByte Dec 17, 2025
f6de272
refactor(project): Use workspace version in stage name
RandomByte Dec 17, 2025
286bdae
refactor(project): Fix stage writer order
RandomByte Dec 17, 2025
eb57dd8
refactor(fs): Add Switch reader
RandomByte Dec 17, 2025
dfe0525
refactor(project): Cleanup WatchHandler debounce
RandomByte Dec 17, 2025
c67dc14
refactor(project): Fix outdated API call
RandomByte Dec 17, 2025
eff6bdb
refactor(project): Fix build signature calculation
RandomByte Dec 17, 2025
6246742
refactor(fs): Pass integrity to cloned resource
RandomByte Dec 17, 2025
d7f5aad
refactor(project): Fix pattern matching and resource comparison
RandomByte Dec 17, 2025
2a4b3a1
refactor(project): Import/overwrite stages from cache after saving
RandomByte Dec 18, 2025
7edbd5d
test(builder): Sort files/folders
matz3 Dec 19, 2025
97f172c
refactor(builder): Prevent duplicate entries on app build from cache
matz3 Dec 19, 2025
0ddf6a4
refactor(fs): Refactor MonitorReader API
RandomByte Dec 23, 2025
50ce097
refactor(fs): Always calculate integrity on clone
RandomByte Dec 24, 2025
a2bee84
refactor(fs): Add getter to WriterCollection
RandomByte Dec 29, 2025
90494e7
refactor(builder): Remove cache handling from tasks
RandomByte Dec 24, 2025
5d50c73
refactor(builder): Add env variable for disabling workers
RandomByte Dec 30, 2025
7e16691
refactor(project): Track resource changes using hash trees
RandomByte Dec 23, 2025
2e4b706
refactor(project): Compress cache using gzip
RandomByte Jan 2, 2026
1b8941b
refactor(fs): Ensure writer collection uses unique readers
RandomByte Jan 2, 2026
8a41de4
refactor(fs): Remove write tracking from MonitoredReaderWriter
RandomByte Jan 2, 2026
45493e0
refactor(project): Identify written resources using stage writer
RandomByte Jan 2, 2026
a2c31bc
refactor(project): Add basic differential update functionality
RandomByte Jan 2, 2026
ed7b323
refactor(builder): Re-add cache handling in tasks
RandomByte Jan 7, 2026
70d04ea
refactor(project): Cleanup HashTree implementation
RandomByte Jan 7, 2026
86a6768
refactor(project): Make WatchHandler wait for build to finish before …
RandomByte Jan 7, 2026
a801c86
refactor(project): Use cleanup hooks in update builds
RandomByte Jan 7, 2026
c3990f2
refactor(logger): Log skipped projects/tasks info in grey color
RandomByte Jan 7, 2026
11748bb
refactor(project): Fix cache update mechanism
RandomByte Jan 7, 2026
d7b8329
refactor(project): WatchHandler emit error event
RandomByte Jan 7, 2026
74f1229
refactor(server): Exit process on rebuild error
RandomByte Jan 7, 2026
4484ae4
refactor(project): Fix delta indices
RandomByte Jan 7, 2026
8d4187d
refactor(logger): Support differential update task logging
RandomByte Jan 8, 2026
0f16779
refactor(project): Provide differential update flag to logger
RandomByte Jan 8, 2026
d2e5732
refactor(server): Log error stack on build error
RandomByte Jan 8, 2026
3e645a8
refactor(project): Add chokidar
RandomByte Jan 8, 2026
d38ff59
refactor(project): Limit build signature to project name and config
RandomByte Jan 8, 2026
7c3b930
refactor(project): Improve ResourceRequestGraph handling
RandomByte Jan 8, 2026
a2e6212
refactor(server): Remove obsolete code from serveResources middleware
matz3 Jan 8, 2026
099bdf0
refactor(project): Add env variable to skip cache update
RandomByte Jan 9, 2026
6a1cd3a
refactor(project): Fix hash tree updates
RandomByte Jan 9, 2026
b5b0632
refactor(project): Remove unused 'cacheDir' param
matz3 Jan 9, 2026
a0a1a64
fix(project): Prevent projects from being always invalidated
matz3 Jan 9, 2026
26f9467
fix(project): Prevent exception when not building in watch mode
matz3 Jan 12, 2026
1e60695
refactor(project): Only store new or modified cache entries
RandomByte Jan 9, 2026
9d2e3e5
refactor(project): Refactor project cache validation
RandomByte Jan 11, 2026
e3365fc
refactor(project): Extract project build into own method
matz3 Jan 13, 2026
2881ed7
fix(project): Clear cleanup task queue
matz3 Jan 13, 2026
cb4abf8
test(project): Add ProjectBuilder integration test
matz3 Jan 13, 2026
818e53b
test(project): Add failing ProjectBuilder test case
matz3 Jan 13, 2026
c97e45b
test(project): Enhance ProjectBuilder test assertions
matz3 Jan 13, 2026
f6ac2a2
test(project): Add library test case for ProjectBuilder
matz3 Jan 13, 2026
83e3dd5
test(project): Build dependencies in application test of ProjectBuilder
matz3 Jan 13, 2026
170d18f
test(project): Refactor ProjectBuilder test code
matz3 Jan 14, 2026
bb968cd
refactor(project): Refactor task resource request tracking
RandomByte Jan 14, 2026
c17217e
test(project): Add theme-library test and update assertions for fixed…
matz3 Jan 14, 2026
06fa058
test(project): Use graph.build for ProjectBuilder test
matz3 Jan 15, 2026
9fe48d2
test(project): Add custom task to ProjectBuilder test
matz3 Jan 15, 2026
6fa2823
fix(project): Fix custom task execution
matz3 Jan 15, 2026
817179a
fix(project): Prevent writing cache when project build was skipped
matz3 Jan 16, 2026
4288d6d
refactor(project): Create dedicated SharedHashTree class
RandomByte Jan 15, 2026
b895e3a
refactor(project): Re-implement differential task build
RandomByte Jan 15, 2026
e4d8eeb
refactor(project): Fix HashTree tests
RandomByte Jan 16, 2026
5e5a7a7
refactor(project): Fix handling cache handling of removed resources
RandomByte Jan 16, 2026
c03f273
test(project): Add cases for theme.library.e with seperate less files
maxreichmann Jan 20, 2026
3a3e9b7
refactor(project): Update graph traversal
RandomByte Jan 20, 2026
9b59587
refactor(project): Add BuildServer and BuildReader
RandomByte Jan 16, 2026
902d449
refactor(project): Refactor project result cache
RandomByte Jan 20, 2026
e751c68
refactor(server): Integrate BuildServer
RandomByte Jan 20, 2026
db9ab01
refactor(project): Small build task cache restructuring, cleanup
RandomByte Jan 20, 2026
c42e6e7
refactor(project): JSDoc cleanup
RandomByte Jan 20, 2026
7cbf40b
refactor(project): ProjectBuilder cleanup
RandomByte Jan 20, 2026
160c050
refactor(builder): Small stringReplacer cleanup
RandomByte Jan 20, 2026
fdb331a
revert(fs): Add Switch reader
RandomByte Jan 20, 2026
418965f
refactor(project): Add perf logging, cleanups
RandomByte Jan 20, 2026
a535812
refactor(project): Add cache write perf logging
RandomByte Jan 20, 2026
485ed57
refactor(project): Improve stage change handling
RandomByte Jan 21, 2026
7209cb8
refactor(project): Implement queue system in BuildServer
matz3 Jan 21, 2026
97c78e6
refactor(server): Add error callback and handle in CLI
RandomByte Jan 21, 2026
14bf2d9
refactor(project): ProjectBuilder to provide callback on project built
RandomByte Jan 21, 2026
8d9261c
refactor(project): Do not always include root project in build
RandomByte Jan 21, 2026
569f24f
refactor(project): Refactor BuildServer init, add tests
RandomByte Jan 21, 2026
0e977d7
refactor(project): Minor ProjectBuildCache and ProjectBuildContext re…
RandomByte Jan 23, 2026
443b6c3
refactor(project): Handle abort signal in ProjectBuilder et al.
RandomByte Jan 23, 2026
55afabe
refactor(project): Refactor BuildServer queue
RandomByte Jan 23, 2026
0af02c9
refactor(project): Fix cache invalidation tracking
RandomByte Jan 23, 2026
a2c371f
refactor(project): Fix stage restore
RandomByte Jan 26, 2026
b57dac5
refactor(project): Add cache support for custom tasks
RandomByte Jan 26, 2026
651481d
test(project): Add file deletion case for theme.library.e
maxreichmann Jan 26, 2026
da88f52
fix(builder): Filter out non-JS resources in minify task
matz3 Jan 26, 2026
349b4f7
test(project): Add test case for minify task fix
matz3 Jan 26, 2026
05d0a34
test(project): Add ResourceRequestManager tests
RandomByte Jan 26, 2026
20370be
refactor(project): Fix derived trees unexpected upsert in parents
RandomByte Jan 26, 2026
83b7ccc
test(project): Adjust test cases for .library changes
matz3 Jan 26, 2026
abd996c
fix: Ensure dot-file matching with micromatch
matz3 Jan 26, 2026
9224dff
test(project): Add test case for ui5.yaml changes
matz3 Jan 26, 2026
39ba915
fix(project): Handle BuildServer race condition when changing files
matz3 Jan 26, 2026
ecc6858
test(project): Remove test.serial.only
matz3 Jan 26, 2026
f28d99d
deps: Fix depcheck issues
matz3 Jan 26, 2026
8c84c4e
test(project): Update ProjectBuildCache and TaskBuildCache tests
RandomByte Jan 26, 2026
a9b68df
test(project): Update ProjectBuilder tests and JSDoc
RandomByte Jan 26, 2026
2837596
test(project): Update TaskRunner tests
RandomByte Jan 26, 2026
223aeb1
test(project): Update various tests
RandomByte Jan 26, 2026
2f89bae
test(project): Add missing comma
matz3 Jan 27, 2026
34b0b1f
refactor(project): Improve abort signal handling
RandomByte Jan 27, 2026
682f2d6
refactor(project): Fix additional tests
RandomByte Jan 27, 2026
6e161e7
refactor(project): Move dependency indice init into PBC
RandomByte Jan 27, 2026
28944c2
fix(project): Improve BuildServer stability on resource changes
matz3 Jan 27, 2026
3583438
test(project): Add case for BuildServer which requests application an…
maxreichmann Jan 27, 2026
9604f19
test(project): Add cases
maxreichmann Jan 28, 2026
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
4,241 changes: 271 additions & 3,970 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/builder/lib/processors/nonAsciiEscaper.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ async function nonAsciiEscaper({resources, options: {encoding}}) {
// only modify the resource's string if it was changed
if (escaped.modified) {
resource.setString(escaped.string);
return resource;
}
return resource;
}

return Promise.all(resources.map(processResource));
Expand Down
3 changes: 2 additions & 1 deletion packages/builder/lib/processors/stringReplacer.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,10 @@ export default function({resources, options: {pattern, replacement}}) {
return Promise.all(resources.map(async (resource) => {
const content = await resource.getString();
const newContent = content.replaceAll(pattern, replacement);
// only modify the resource's string if it was changed
if (content !== newContent) {
resource.setString(newContent);
return resource;
}
return resource;
}));
}
2 changes: 1 addition & 1 deletion packages/builder/lib/tasks/buildThemes.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ export default async function({
}

let processedResources;
const useWorkers = !!taskUtil;
const useWorkers = !process.env.UI5_CLI_NO_WORKERS && !!taskUtil;
if (useWorkers) {
const threadMessageHandler = new FsMainThreadInterface(fsInterface(combo));

Expand Down
13 changes: 10 additions & 3 deletions packages/builder/lib/tasks/escapeNonAsciiCharacters.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,24 @@ import nonAsciiEscaper from "../processors/nonAsciiEscaper.js";
*
* @param {object} parameters Parameters
* @param {@ui5/fs/DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {string[]} [parameters.changedProjectResourcePaths] Set of changed resource paths within the project.
* This is only set if a cache is used and changes have been detected.
* @param {object} parameters.options Options
* @param {string} parameters.options.pattern Glob pattern to locate the files to be processed
* @param {string} parameters.options.encoding source file encoding either "UTF-8" or "ISO-8859-1"
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
export default async function({workspace, options: {pattern, encoding}}) {
export default async function({workspace, changedProjectResourcePaths, options: {pattern, encoding}}) {
if (!encoding) {
throw new Error("[escapeNonAsciiCharacters] Mandatory option 'encoding' not provided");
}

const allResources = await workspace.byGlob(pattern);
let allResources;
if (changedProjectResourcePaths) {
allResources = await Promise.all(changedProjectResourcePaths.map((resource) => workspace.byPath(resource)));
} else {
allResources = await workspace.byGlob(pattern);
}

const processedResources = await nonAsciiEscaper({
resources: allResources,
Expand All @@ -33,5 +40,5 @@ export default async function({workspace, options: {pattern, encoding}}) {
}
});

await Promise.all(processedResources.map((resource) => workspace.write(resource)));
await Promise.all(processedResources.map((resource) => resource && workspace.write(resource)));
}
25 changes: 21 additions & 4 deletions packages/builder/lib/tasks/minify.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import fsInterface from "@ui5/fs/fsInterface";
* @param {object} parameters Parameters
* @param {@ui5/fs/DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {@ui5/project/build/helpers/TaskUtil|object} [parameters.taskUtil] TaskUtil
* @param {string[]} [parameters.changedProjectResourcePaths] Set of changed resource paths within the project.
* This is only set if a cache is used and changes have been detected.
* @param {object} parameters.options Options
* @param {string} parameters.options.pattern Pattern to locate the files to be processed
* @param {boolean} [parameters.options.omitSourceMapResources=false] Whether source map resources shall
Expand All @@ -26,17 +28,32 @@ import fsInterface from "@ui5/fs/fsInterface";
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
export default async function({
workspace, taskUtil, options: {pattern, omitSourceMapResources = false, useInputSourceMaps = true
}}) {
const resources = await workspace.byGlob(pattern);
workspace, taskUtil, changedProjectResourcePaths,
options: {pattern, omitSourceMapResources = false, useInputSourceMaps = true}
}) {
let resources;
if (changedProjectResourcePaths) {
resources = await Promise.all(
changedProjectResourcePaths
// Filtering out non-JS resources such as .map files
// FIXME: The changed resources should rather be matched against the provided pattern
.filter((resourcePath) => resourcePath.endsWith(".js"))
.map((resource) => workspace.byPath(resource))
);
} else {
resources = await workspace.byGlob(pattern);
}
if (resources.length === 0) {
return;
}
const processedResources = await minifier({
resources,
fs: fsInterface(workspace),
taskUtil,
options: {
addSourceMappingUrl: !omitSourceMapResources,
readSourceMappingUrl: !!useInputSourceMaps,
useWorkers: !!taskUtil,
useWorkers: !process.env.UI5_CLI_NO_WORKERS && !!taskUtil,
}
});

Expand Down
38 changes: 21 additions & 17 deletions packages/builder/lib/tasks/replaceBuildtime.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,30 @@ function getTimestamp() {
*
* @param {object} parameters Parameters
* @param {@ui5/fs/DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {string[]} [parameters.changedProjectResourcePaths] Set of changed resource paths within the project.
* This is only set if a cache is used and changes have been detected.
* @param {object} parameters.options Options
* @param {string} parameters.options.pattern Pattern to locate the files to be processed
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
export default function({workspace, options: {pattern}}) {
export default async function({workspace, changedProjectResourcePaths, options: {pattern}}) {
let resources;
if (changedProjectResourcePaths) {
resources = await Promise.all(changedProjectResourcePaths.map((resource) => workspace.byPath(resource)));
} else {
resources = await workspace.byGlob(pattern);
}
const timestamp = getTimestamp();

return workspace.byGlob(pattern)
.then((processedResources) => {
return stringReplacer({
resources: processedResources,
options: {
pattern: "${buildtime}",
replacement: timestamp
}
});
})
.then((processedResources) => {
return Promise.all(processedResources.map((resource) => {
return workspace.write(resource);
}));
});
const processedResources = await stringReplacer({
resources,
options: {
pattern: "${buildtime}",
replacement: timestamp
}
});
return Promise.all(processedResources.map((resource) => {
if (resource) {
return workspace.write(resource);
}
}));
}
40 changes: 23 additions & 17 deletions packages/builder/lib/tasks/replaceCopyright.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,32 +24,38 @@ import stringReplacer from "../processors/stringReplacer.js";
*
* @param {object} parameters Parameters
* @param {@ui5/fs/DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {string[]} [parameters.changedProjectResourcePaths] Set of changed resource paths within the project.
* This is only set if a cache is used and changes have been detected.
* @param {object} parameters.options Options
* @param {string} parameters.options.copyright Replacement copyright
* @param {string} parameters.options.pattern Pattern to locate the files to be processed
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
export default function({workspace, options: {copyright, pattern}}) {
export default async function({workspace, changedProjectResourcePaths, options: {copyright, pattern}}) {
if (!copyright) {
return Promise.resolve();
return;
}

// Replace optional placeholder ${currentYear} with the current year
copyright = copyright.replace(/(?:\$\{currentYear\})/, new Date().getFullYear());

return workspace.byGlob(pattern)
.then((processedResources) => {
return stringReplacer({
resources: processedResources,
options: {
pattern: /(?:\$\{copyright\}|@copyright@)/g,
replacement: copyright
}
});
})
.then((processedResources) => {
return Promise.all(processedResources.map((resource) => {
return workspace.write(resource);
}));
});
let resources;
if (changedProjectResourcePaths) {
resources = await Promise.all(changedProjectResourcePaths.map((resource) => workspace.byPath(resource)));
} else {
resources = await workspace.byGlob(pattern);
}

const processedResources = await stringReplacer({
resources,
options: {
pattern: /(?:\$\{copyright\}|@copyright@)/g,
replacement: copyright
}
});
return Promise.all(processedResources.map((resource) => {
if (resource) {
return workspace.write(resource);
}
}));
}
37 changes: 21 additions & 16 deletions packages/builder/lib/tasks/replaceVersion.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,30 @@ import stringReplacer from "../processors/stringReplacer.js";
*
* @param {object} parameters Parameters
* @param {@ui5/fs/DuplexCollection} parameters.workspace DuplexCollection to read and write files
* @param {string[]} [parameters.changedProjectResourcePaths] Set of changed resource paths within the project.
* This is only set if a cache is used and changes have been detected.
* @param {object} parameters.options Options
* @param {string} parameters.options.pattern Pattern to locate the files to be processed
* @param {string} parameters.options.version Replacement version
* @returns {Promise<undefined>} Promise resolving with <code>undefined</code> once data has been written
*/
export default function({workspace, options: {pattern, version}}) {
return workspace.byGlob(pattern)
.then((allResources) => {
return stringReplacer({
resources: allResources,
options: {
pattern: /\$\{(?:project\.)?version\}/g,
replacement: version
}
});
})
.then((processedResources) => {
return Promise.all(processedResources.map((resource) => {
return workspace.write(resource);
}));
});
export default async function({workspace, changedProjectResourcePaths, options: {pattern, version}}) {
let resources;
if (changedProjectResourcePaths) {
resources = await Promise.all(changedProjectResourcePaths.map((resource) => workspace.byPath(resource)));
} else {
resources = await workspace.byGlob(pattern);
}
const processedResources = await stringReplacer({
resources,
options: {
pattern: /\$\{(?:project\.)?version\}/g,
replacement: version
}
});
await Promise.all(processedResources.map((resource) => {
if (resource) {
return workspace.write(resource);
}
}));
}
4 changes: 2 additions & 2 deletions packages/builder/test/utils/fshelper.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ export async function readFileContent(filePath) {
}

export async function directoryDeepEqual(t, destPath, expectedPath) {
const dest = await readdir(destPath, {recursive: true});
const expected = await readdir(expectedPath, {recursive: true});
const dest = (await readdir(destPath, {recursive: true})).sort();
const expected = (await readdir(expectedPath, {recursive: true})).sort();
t.deepEqual(dest, expected);
}

Expand Down
2 changes: 2 additions & 0 deletions packages/cli/lib/cli/commands/build.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import baseMiddleware from "../middlewares/base.js";
import path from "node:path";

const build = {
command: "build",
Expand Down Expand Up @@ -173,6 +174,7 @@ async function handleBuild(argv) {
const buildSettings = graph.getRoot().getBuilderSettings() || {};
await graph.build({
graph,
cacheDir: path.join(graph.getRoot().getRootPath(), ".ui5-cache"),
destPath: argv.dest,
cleanDest: argv["clean-dest"],
createBuildManifest: argv["create-build-manifest"],
Expand Down
6 changes: 5 additions & 1 deletion packages/cli/lib/cli/commands/serve.js
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,10 @@ serve.handler = async function(argv) {
serverConfig.cert = cert;
}

const {h2, port: actualPort} = await serverServe(graph, serverConfig);
const {promise: pOnError, reject} = Promise.withResolvers();
const {h2, port: actualPort} = await serverServe(graph, serverConfig, function(err) {
reject(err);
});

const protocol = h2 ? "https" : "http";
let browserUrl = protocol + "://localhost:" + actualPort;
Expand Down Expand Up @@ -183,6 +186,7 @@ serve.handler = async function(argv) {
const {default: open} = await import("open");
open(browserUrl);
}
await pOnError; // Await errors that should bubble into the yargs handler
};

export default serve;
49 changes: 49 additions & 0 deletions packages/fs/lib/MonitoredReader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import AbstractReader from "./AbstractReader.js";

export default class MonitoredReader extends AbstractReader {
#reader;
#sealed = false;
#paths = [];
#patterns = [];

constructor(reader) {
super(reader.getName());
this.#reader = reader;
}

getResourceRequests() {
this.#sealed = true;
return {
paths: this.#paths,
patterns: this.#patterns,
};
}

async _byGlob(virPattern, options, trace) {
if (this.#sealed) {
throw new Error(`Unexpected read operation after reader has been sealed`);
}
if (this.#reader.resolvePattern) {
const resolvedPattern = this.#reader.resolvePattern(virPattern);
this.#patterns.push(resolvedPattern);
} else {
this.#patterns.push(virPattern);
}
return await this.#reader._byGlob(virPattern, options, trace);
}

async _byPath(virPath, options, trace) {
if (this.#sealed) {
throw new Error(`Unexpected read operation after reader has been sealed`);
}
if (this.#reader.resolvePath) {
const resolvedPath = this.#reader.resolvePath(virPath);
if (resolvedPath) {
this.#paths.push(resolvedPath);
}
} else {
this.#paths.push(virPath);
}
return await this.#reader._byPath(virPath, options, trace);
}
}
Loading
Loading