Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
195 commits
Select commit Hold shift + click to select a range
6922ede
feat(fs): Enhance API for incremental build, add tracking readers/wri…
RandomByte Nov 18, 2025
15ff48f
feat(server): Use incremental build in server
RandomByte Nov 18, 2025
479b991
feat(builder): Adapt tasks for incremental build
RandomByte Nov 18, 2025
29bde91
refactor(project): Align getReader API internals with ComponentProjects
RandomByte Nov 18, 2025
e69b151
refactor(project): Refactor specification-internal workspace handling
RandomByte Nov 18, 2025
79ab544
refactor(project): Implement basic incremental build functionality
RandomByte Nov 18, 2025
44c29fd
refactor(cli): Use cache in ui5 build
RandomByte Nov 18, 2025
1fc6612
refactor(project): Use cacache
RandomByte Nov 24, 2025
618a33d
refactor(project): Add cache manager
RandomByte Nov 28, 2025
0fd06b6
refactor(fs): Refactor Resource internals
RandomByte Nov 27, 2025
278da47
refactor(fs): Provide createBuffer factory in FileSystem adapter
RandomByte Dec 1, 2025
f66d55d
refactor(project): Refactor cache classes
RandomByte Dec 1, 2025
eebb45b
refactor(fs): Add Proxy reader
RandomByte Dec 4, 2025
00e6fa9
refactor(project): API refactoring
RandomByte Dec 8, 2025
6604ccb
refactor(builder): Rename task param 'buildCache' to 'cacheUtil'
RandomByte Dec 10, 2025
2bdc079
refactor(project): Cleanup
RandomByte Dec 10, 2025
ecb5a94
refactor(project): Move resource comparison to util
RandomByte Dec 12, 2025
58bdae7
refactor(project): Refactor stage handling
RandomByte Dec 16, 2025
7a15733
refactor(project): Fix cache handling
RandomByte Dec 16, 2025
81780ea
refactor(fs): Remove contentAccess mutex timeout from Resource
RandomByte Dec 16, 2025
4f06083
refactor(project): Cleanup obsolete code/comments
RandomByte Dec 16, 2025
691aec1
refactor(server): Cleanup obsolete code
RandomByte Dec 16, 2025
b11688a
refactor(project): Rename watch handler events
RandomByte Dec 16, 2025
9e84bfc
refactor: Fix linting issues
matz3 Dec 17, 2025
d8c4dfc
test(fs): Adjust getIntegrity tests
matz3 Dec 17, 2025
e08c76b
refactor: Integrity handling
matz3 Dec 17, 2025
ec9f7a3
test(fs): Adjust getIntegrity tests again
matz3 Dec 17, 2025
615b38d
refactor: Consider npm-shrinkwrap.json
matz3 Dec 17, 2025
4279109
refactor: Rename Tracker => MonitoredReader
RandomByte Dec 17, 2025
099d248
refactor(project): Use workspace version in stage name
RandomByte Dec 17, 2025
6e47044
refactor(project): Fix stage writer order
RandomByte Dec 17, 2025
4f465ae
refactor(fs): Add Switch reader
RandomByte Dec 17, 2025
56f695a
refactor(project): Cleanup WatchHandler debounce
RandomByte Dec 17, 2025
495607d
refactor(project): Fix outdated API call
RandomByte Dec 17, 2025
78b0be1
refactor(project): Fix build signature calculation
RandomByte Dec 17, 2025
58cdba8
refactor(fs): Pass integrity to cloned resource
RandomByte Dec 17, 2025
8beb29c
refactor(project): Fix pattern matching and resource comparison
RandomByte Dec 17, 2025
ebc6783
refactor(project): Import/overwrite stages from cache after saving
RandomByte Dec 18, 2025
edb6ae8
test(builder): Sort files/folders
matz3 Dec 19, 2025
4fced41
refactor(builder): Prevent duplicate entries on app build from cache
matz3 Dec 19, 2025
45c384b
refactor(fs): Refactor MonitorReader API
RandomByte Dec 23, 2025
2426ce3
refactor(fs): Always calculate integrity on clone
RandomByte Dec 24, 2025
dc72db2
refactor(fs): Add getter to WriterCollection
RandomByte Dec 29, 2025
25aeb8f
refactor(builder): Remove cache handling from tasks
RandomByte Dec 24, 2025
1c255de
refactor(builder): Add env variable for disabling workers
RandomByte Dec 30, 2025
49cf9af
refactor(project): Track resource changes using hash trees
RandomByte Dec 23, 2025
895f08a
refactor(project): Compress cache using gzip
RandomByte Jan 2, 2026
4e898ce
refactor(fs): Ensure writer collection uses unique readers
RandomByte Jan 2, 2026
c32c50c
refactor(fs): Remove write tracking from MonitoredReaderWriter
RandomByte Jan 2, 2026
f8599cd
refactor(project): Identify written resources using stage writer
RandomByte Jan 2, 2026
56819d4
refactor(project): Add basic differential update functionality
RandomByte Jan 2, 2026
859dadd
refactor(builder): Re-add cache handling in tasks
RandomByte Jan 7, 2026
037b54f
refactor(project): Cleanup HashTree implementation
RandomByte Jan 7, 2026
78cdc84
refactor(project): Make WatchHandler wait for build to finish before …
RandomByte Jan 7, 2026
f609e57
refactor(project): Use cleanup hooks in update builds
RandomByte Jan 7, 2026
3050a19
refactor(logger): Log skipped projects/tasks info in grey color
RandomByte Jan 7, 2026
8bbbafe
refactor(project): Fix cache update mechanism
RandomByte Jan 7, 2026
cd5a4e6
refactor(project): WatchHandler emit error event
RandomByte Jan 7, 2026
f504b29
refactor(server): Exit process on rebuild error
RandomByte Jan 7, 2026
2e4c23b
refactor(project): Fix delta indices
RandomByte Jan 7, 2026
26d404f
refactor(logger): Support differential update task logging
RandomByte Jan 8, 2026
008a196
refactor(project): Provide differential update flag to logger
RandomByte Jan 8, 2026
45cd457
refactor(server): Log error stack on build error
RandomByte Jan 8, 2026
8614e37
refactor(project): Add chokidar
RandomByte Jan 8, 2026
38c79e1
refactor(project): Limit build signature to project name and config
RandomByte Jan 8, 2026
db8af75
refactor(project): Improve ResourceRequestGraph handling
RandomByte Jan 8, 2026
438d0c2
refactor(server): Remove obsolete code from serveResources middleware
matz3 Jan 8, 2026
0e16bf3
refactor(project): Add env variable to skip cache update
RandomByte Jan 9, 2026
3ea7fe5
refactor(project): Fix hash tree updates
RandomByte Jan 9, 2026
4f1ca7b
refactor(project): Remove unused 'cacheDir' param
matz3 Jan 9, 2026
95401d5
fix(project): Prevent projects from being always invalidated
matz3 Jan 9, 2026
2631d08
fix(project): Prevent exception when not building in watch mode
matz3 Jan 12, 2026
9ca3474
refactor(project): Only store new or modified cache entries
RandomByte Jan 9, 2026
037f27c
refactor(project): Refactor project cache validation
RandomByte Jan 11, 2026
b6304bf
refactor(project): Extract project build into own method
matz3 Jan 13, 2026
3ed2436
fix(project): Clear cleanup task queue
matz3 Jan 13, 2026
39547e6
test(project): Add ProjectBuilder integration test
matz3 Jan 13, 2026
721161f
test(project): Add failing ProjectBuilder test case
matz3 Jan 13, 2026
c51baed
test(project): Enhance ProjectBuilder test assertions
matz3 Jan 13, 2026
8a41c19
test(project): Add library test case for ProjectBuilder
matz3 Jan 13, 2026
dd2b87d
test(project): Build dependencies in application test of ProjectBuilder
matz3 Jan 13, 2026
520b7d4
test(project): Refactor ProjectBuilder test code
matz3 Jan 14, 2026
7407906
refactor(project): Refactor task resource request tracking
RandomByte Jan 14, 2026
7723cfd
test(project): Add theme-library test and update assertions for fixed…
matz3 Jan 14, 2026
3e1ecf4
test(project): Use graph.build for ProjectBuilder test
matz3 Jan 15, 2026
cca52a1
test(project): Add custom task to ProjectBuilder test
matz3 Jan 15, 2026
7d81efd
fix(project): Fix custom task execution
matz3 Jan 15, 2026
b9ad94b
fix(project): Prevent writing cache when project build was skipped
matz3 Jan 16, 2026
83d65a5
refactor(project): Create dedicated SharedHashTree class
RandomByte Jan 15, 2026
a9ddf5c
refactor(project): Re-implement differential task build
RandomByte Jan 15, 2026
8b9a6c8
refactor(project): Fix HashTree tests
RandomByte Jan 16, 2026
6f586d7
refactor(project): Fix handling cache handling of removed resources
RandomByte Jan 16, 2026
e8b8163
test(project): Add cases for theme.library.e with seperate less files
maxreichmann Jan 20, 2026
76cf1b3
refactor(project): Update graph traversal
RandomByte Jan 20, 2026
89a3c8d
refactor(project): Add BuildServer and BuildReader
RandomByte Jan 16, 2026
77d4b79
refactor(project): Refactor project result cache
RandomByte Jan 20, 2026
770a335
refactor(server): Integrate BuildServer
RandomByte Jan 20, 2026
22106b4
refactor(project): Small build task cache restructuring, cleanup
RandomByte Jan 20, 2026
85b04bc
refactor(project): JSDoc cleanup
RandomByte Jan 20, 2026
e4bed70
refactor(project): ProjectBuilder cleanup
RandomByte Jan 20, 2026
d8a7ec7
refactor(builder): Small stringReplacer cleanup
RandomByte Jan 20, 2026
f65ecc4
revert(fs): Add Switch reader
RandomByte Jan 20, 2026
03de20e
refactor(project): Add perf logging, cleanups
RandomByte Jan 20, 2026
16119f4
refactor(project): Add cache write perf logging
RandomByte Jan 20, 2026
86f90ad
refactor(project): Improve stage change handling
RandomByte Jan 21, 2026
b5cb12a
refactor(project): Implement queue system in BuildServer
matz3 Jan 21, 2026
5ce08c9
refactor(server): Add error callback and handle in CLI
RandomByte Jan 21, 2026
e85b664
refactor(project): ProjectBuilder to provide callback on project built
RandomByte Jan 21, 2026
3743a4d
refactor(project): Do not always include root project in build
RandomByte Jan 21, 2026
9a1fd9d
refactor(project): Refactor BuildServer init, add tests
RandomByte Jan 21, 2026
9d42d14
refactor(project): Minor ProjectBuildCache and ProjectBuildContext re…
RandomByte Jan 23, 2026
62d36c2
refactor(project): Handle abort signal in ProjectBuilder et al.
RandomByte Jan 23, 2026
f1e1062
refactor(project): Refactor BuildServer queue
RandomByte Jan 23, 2026
5f6403c
refactor(project): Fix cache invalidation tracking
RandomByte Jan 23, 2026
8dad3be
refactor(project): Fix stage restore
RandomByte Jan 26, 2026
41446e5
refactor(project): Add cache support for custom tasks
RandomByte Jan 26, 2026
1f62911
test(project): Add file deletion case for theme.library.e
maxreichmann Jan 26, 2026
972efca
fix(builder): Filter out non-JS resources in minify task
matz3 Jan 26, 2026
becd2bd
test(project): Add test case for minify task fix
matz3 Jan 26, 2026
13b96ee
test(project): Add ResourceRequestManager tests
RandomByte Jan 26, 2026
5193cdc
refactor(project): Fix derived trees unexpected upsert in parents
RandomByte Jan 26, 2026
56a6e47
test(project): Adjust test cases for .library changes
matz3 Jan 26, 2026
53e4da2
fix: Ensure dot-file matching with micromatch
matz3 Jan 26, 2026
c7765f4
test(project): Add test case for ui5.yaml changes
matz3 Jan 26, 2026
33e3524
fix(project): Handle BuildServer race condition when changing files
matz3 Jan 26, 2026
71fcbd0
test(project): Remove test.serial.only
matz3 Jan 26, 2026
fdd4941
deps: Fix depcheck issues
matz3 Jan 26, 2026
3026da7
test(project): Update ProjectBuildCache and TaskBuildCache tests
RandomByte Jan 26, 2026
436b52e
test(project): Update ProjectBuilder tests and JSDoc
RandomByte Jan 26, 2026
c8eacab
test(project): Update TaskRunner tests
RandomByte Jan 26, 2026
858aee6
test(project): Update various tests
RandomByte Jan 26, 2026
778d624
test(project): Add missing comma
matz3 Jan 27, 2026
309ba03
refactor(project): Improve abort signal handling
RandomByte Jan 27, 2026
9fde81c
refactor(project): Fix additional tests
RandomByte Jan 27, 2026
cf983b2
refactor(project): Move dependency indice init into PBC
RandomByte Jan 27, 2026
77459c7
fix(project): Improve BuildServer stability on resource changes
matz3 Jan 27, 2026
1a84cd3
test(project): Add case for BuildServer which requests application an…
maxreichmann Jan 27, 2026
8f674c4
test(project): Add cases
maxreichmann Jan 28, 2026
a26d381
test(project): Add cases for project type "module" (ProjectBuilder)
maxreichmann Jan 29, 2026
c8a8a53
refactor(project): ProjectBuildCache state handling
RandomByte Jan 28, 2026
214c5fe
test(project): Update node_modules deps to be aligned with actual fix…
maxreichmann Feb 4, 2026
1437a13
test(project): Add "library" dependencies to "module" fixture
maxreichmann Feb 5, 2026
d90a002
test(project): Update ProjectBuildContext tests
matz3 Feb 9, 2026
4e85900
Revert "test(project): Update node_modules deps to be aligned with ac…
maxreichmann Feb 10, 2026
32b936c
refactor(project): Rename task param 'supportsDifferentialUpdates' =>…
RandomByte Feb 10, 2026
2c9f017
test(project): Extend FixtureTester (ProjectBuilder) to work with non…
maxreichmann Feb 10, 2026
d953aa2
test(project): Add cases for ui5.yaml path mapping (Modules)
maxreichmann Feb 10, 2026
0b260e9
test(project): Add race condition test
RandomByte Feb 10, 2026
7edfa90
test(project): Add modify file case for modules
maxreichmann Feb 11, 2026
2872221
test(project): Add case for multiple custom tasks (tag handling)
maxreichmann Feb 16, 2026
48f68c4
fix(project): Fix build manifest access
matz3 Feb 18, 2026
5819f35
test(project): Fix multiple-task tests (Address review)
maxreichmann Feb 18, 2026
bf1e2f1
test(project): Re-Add eslint rule (removed by accident)
maxreichmann Feb 18, 2026
585274f
refactor(fs): Add MonitoredResourceTagCollection
RandomByte Feb 23, 2026
ee69203
refactor(project): Add basic handling for resource tags
RandomByte Feb 23, 2026
38db9d6
test(project): Add another multiple-task / tag handling case
maxreichmann Feb 25, 2026
67d12c0
test(project): Add case for dependency content changes
maxreichmann Feb 26, 2026
523a842
test(project): Clean-up temporary comments
maxreichmann Feb 27, 2026
fe8e73e
test(project): Add case for JSDoc builds (Standard Tasks)
maxreichmann Mar 5, 2026
576b2c2
test(project): Address review of @RandomByte
maxreichmann Mar 5, 2026
bf3fab9
refactor(project): Enhance build cache logging for signatures
RandomByte Mar 5, 2026
8c55d8e
test(project): Add basic library build test for BuildServer
RandomByte Mar 5, 2026
1781b83
test(project): Add cases for custom preload configs (for application,…
maxreichmann Mar 5, 2026
38c0e4b
refactor(project): Adapt tests after refactoring of resource tag hand…
RandomByte Mar 6, 2026
97da538
refactor(fs): Fix resource integrity for resources without content
RandomByte Mar 6, 2026
21131a1
test(logger): Fix tests
RandomByte Mar 6, 2026
67e093f
test(project): Add case for self-contained builds (Standard Tasks)
maxreichmann Mar 6, 2026
0320840
refactor(project): Fix incorrect stage signature when using delta sta…
RandomByte Mar 9, 2026
9911060
test(project): Add cases for custom bundling builds
maxreichmann Mar 9, 2026
3ab250f
test(project): Add cases for file deletion (TC4)
d3xter666 Mar 10, 2026
2367066
test(project): Refactor "custom tasks 2" case
maxreichmann Mar 10, 2026
4f233f9
test(project): Add tests for various dependency relations
maxreichmann Mar 10, 2026
e5d23d7
test(project): Add cases for race condition (add/remove file)
d3xter666 Mar 16, 2026
35b0bf2
refactor(project): Cleanup cache state handling
RandomByte Mar 11, 2026
dbc13fc
feat(project): Incorporate resource tags into hash tree leaf node hashes
RandomByte Mar 10, 2026
a09355e
refactor(fs): Add ResourceTagCollection#getAllTagsForResource method
RandomByte Mar 11, 2026
aae6058
refactor(project): Add test for cross-project resource tag handling
RandomByte Mar 12, 2026
7911d15
refactor(fs): Expose getTags method on resource
RandomByte Mar 12, 2026
a212836
refactor(project): Fix tag handling, align test
RandomByte Mar 13, 2026
31c2427
refactor(project): Improve build abort handling, ease race-condition …
RandomByte Mar 16, 2026
63e7dff
refactor(project): Cleanup comment
RandomByte Mar 16, 2026
7c90857
test(project): Add case for --include-dependency (Cover build with on…
maxreichmann Mar 16, 2026
6295b10
test(project): Check if sap-ui-version.json contains correct content
d3xter666 Mar 18, 2026
2255545
test(project): Add case for removing a dependency
maxreichmann Mar 19, 2026
766deb1
refactor(project): Validate source files after build finishes
RandomByte Mar 19, 2026
67a6d91
refactor(project): Store source files in CAS
RandomByte Mar 19, 2026
93190ea
refactor(project): Use stored source files in ProjectResources
RandomByte Mar 19, 2026
568692e
test(project): Add tests for cross project source file modifications
RandomByte Mar 19, 2026
ed4a117
test(internal): Add new "e2e-tests" dir to internal/
maxreichmann Mar 27, 2026
88b42af
test: E2E-tests: Fix child process security
maxreichmann Apr 1, 2026
b3841d4
test: E2E-tests: Cover scenario for "ui5-task-zipper"
maxreichmann Apr 2, 2026
71ddb60
test: E2E-tests: Cover scenario for "ui5-tooling-modules"
maxreichmann Apr 2, 2026
4dc9a0e
test: E2E-tests: Cover scenario for "ui5-tooling-stringreplace" (Curr…
maxreichmann Apr 2, 2026
fe5158b
test: E2E-tests: Adjust readme
maxreichmann Apr 2, 2026
17bfe1c
test: Remove E2E-test
maxreichmann Apr 8, 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
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,7 @@ internal/documentation/.vitepress/cache
internal/documentation/dist
internal/documentation/schema/*
internal/documentation/docs/api
internal/documentation/tmp
internal/documentation/tmp

# E2E tests
internal/e2e-tests/tmp
4,951 changes: 607 additions & 4,344 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