@@ -6,7 +6,6 @@ import baseMiddleware from "../middlewares/base.js";
66import { getUi5DataDir } from "../../framework/utils.js" ;
77import * as frameworkCache from "@ui5/project/ui5Framework/cache" ;
88import CacheManager from "@ui5/project/build/cache/CacheManager" ;
9- import prettyHrtime from "pretty-hrtime" ;
109
1110const cacheCommand = {
1211 command : "cache" ,
@@ -33,7 +32,17 @@ cacheCommand.builder = function(cli) {
3332 . example ( "$0 cache clean --yes" ,
3433 "Remove all cached UI5 data without confirmation (e.g. in CI)" )
3534 . example ( "UI5_DATA_DIR=/custom/path $0 cache clean" ,
36- "Remove cached data from a non-default UI5 data directory" ) ;
35+ "Remove cached data from a non-default UI5 data directory" )
36+ . epilogue (
37+ "The cache is stored in the UI5 data directory (default: ~/.ui5).\n" +
38+ "Override the location with the UI5_DATA_DIR environment variable or\n" +
39+ "the 'ui5DataDir' configuration option (see 'ui5 config --help').\n\n" +
40+ "Two cache types are removed:\n" +
41+ " UI5 Framework packages Downloaded UI5 library files " +
42+ "(~/.ui5/framework/)\n" +
43+ " Build cache (DB) Incremental build data " +
44+ "(~/.ui5/buildCache/)"
45+ ) ;
3746 } ,
3847 middlewares : [ baseMiddleware ] ,
3948 } ) ;
@@ -62,19 +71,17 @@ function formatSize(bytes) {
6271}
6372
6473/**
65- * Format a library stats detail string, e.g. "2 projects, 3 libraries, 4 versions" .
66- * Each word is independently singular/plural .
74+ * Format framework cache stats as a human-readable detail string .
75+ * E.g. "1,189 versions of 155 libraries" or "1 version of 1 library" .
6776 *
6877 * @param {number } libraryCount
69- * @param {number } projectCount
7078 * @param {number } versionCount
7179 * @returns {string }
7280 */
73- function formatLibraryStats ( libraryCount , projectCount , versionCount ) {
74- const p = `${ projectCount } ${ projectCount === 1 ? "project" : "projects" } ` ;
75- const l = `${ libraryCount } ${ libraryCount === 1 ? "library" : "libraries" } ` ;
76- const v = `${ versionCount } ${ versionCount === 1 ? "version" : "versions" } ` ;
77- return `${ p } , ${ l } , ${ v } ` ;
81+ function formatFrameworkStats ( libraryCount , versionCount ) {
82+ const v = `${ versionCount . toLocaleString ( "en-US" ) } ${ versionCount === 1 ? "version" : "versions" } ` ;
83+ const l = `${ libraryCount . toLocaleString ( "en-US" ) } ${ libraryCount === 1 ? "library" : "libraries" } ` ;
84+ return `${ v } of ${ l } ` ;
7885}
7986
8087/**
@@ -87,64 +94,6 @@ function padLabel(label) {
8794 return label . padEnd ( LABEL_WIDTH ) ;
8895}
8996
90- const SPINNER_FRAMES = [ "⠋" , "⠙" , "⠹" , "⠸" , "⠼" , "⠴" , "⠦" , "⠧" , "⠇" , "⠏" ] ;
91- const PROGRESS_DEBOUNCE_MS = 150 ;
92- // Reserve enough columns for the fixed parts of the progress line so the path
93- // never causes the line to wrap on a standard 80-column terminal.
94- const PATH_MAX_COLS = 40 ;
95-
96- /**
97- * Build a progress handler for framework cache deletion.
98- * Returns a function to pass as onProgress to cleanCache(), plus a finalise()
99- * to call when deletion completes (clears the in-progress line).
100- *
101- * The line is written to stderr with \r so it overwrites itself on each tick,
102- * producing a single updating line rather than a scrolling log.
103- *
104- * @param {string } label Short label shown on the progress line
105- * @param {Array } startHrtime process.hrtime() snapshot taken when deletion began
106- * @param {Function } prettyHrtime Formatting function from the pretty-hrtime package
107- * @returns {{onProgress: function(string): void, finalise: function(): void} }
108- */
109- function createProgressHandler ( label , startHrtime , prettyHrtime ) {
110- let lastPrintMs = 0 ;
111- let frameIndex = 0 ;
112- let lastVisibleLen = 0 ;
113-
114- function onProgress ( entryPath ) {
115- const now = Date . now ( ) ;
116- if ( now - lastPrintMs < PROGRESS_DEBOUNCE_MS ) return ;
117- lastPrintMs = now ;
118-
119- const elapsed = prettyHrtime ( process . hrtime ( startHrtime ) ) ;
120- const spinner = SPINNER_FRAMES [ frameIndex % SPINNER_FRAMES . length ] ;
121- frameIndex ++ ;
122-
123- // Trim path so the whole line stays within 80 columns
124- let displayPath = entryPath ;
125- if ( displayPath . length > PATH_MAX_COLS ) {
126- displayPath = "…" + displayPath . slice ( - ( PATH_MAX_COLS - 1 ) ) ;
127- }
128-
129- // Build visible text (no ANSI) first to get accurate length for overwrite padding
130- const visibleText = ` ${ spinner } ${ label } ${ displayPath } ${ elapsed } ` ;
131- // Then the styled version for actual output
132- const styledText = ` ${ spinner } ${ label } ${ chalk . dim ( displayPath ) } ${ elapsed } ` ;
133-
134- // Pad to cover any longer previous line, then overwrite in place
135- const padded = styledText + " " . repeat ( Math . max ( 0 , lastVisibleLen - visibleText . length ) ) ;
136- lastVisibleLen = visibleText . length ;
137-
138- process . stderr . write ( `\r${ padded } ` ) ;
139- }
140-
141- function finalise ( ) {
142- process . stderr . write ( `\r${ " " . repeat ( lastVisibleLen ) } \r` ) ;
143- }
144-
145- return { onProgress, finalise} ;
146- }
147-
14897async function handleCache ( argv ) {
14998 // Resolve UI5 data directory — uses the same resolution chain as ui5 build/serve:
15099 // UI5_DATA_DIR env var → ui5DataDir config (~/.ui5rc) → default ~/.ui5
@@ -185,8 +134,7 @@ async function handleCache(argv) {
185134 // Display items that will be removed
186135 process . stderr . write ( chalk . bold ( "\nThe following cached data will be removed:\n\n" ) ) ;
187136 if ( frameworkInfo ) {
188- const detail = formatLibraryStats (
189- frameworkInfo . libraryCount , frameworkInfo . projectCount , frameworkInfo . versionCount ) ;
137+ const detail = formatFrameworkStats ( frameworkInfo . libraryCount , frameworkInfo . versionCount ) ;
190138 process . stderr . write (
191139 ` ${ chalk . yellow ( "•" ) } ${ padLabel ( LABEL_FRAMEWORK ) } ${ frameworkAbsPath } (${ detail } )\n`
192140 ) ;
@@ -213,22 +161,12 @@ async function handleCache(argv) {
213161 }
214162
215163 // Perform the actual cleanup (orchestrate both domains)
216- let frameworkResult ;
217- if ( frameworkInfo ) {
218- const startHrtime = process . hrtime ( ) ;
219- const { onProgress, finalise} = createProgressHandler ( LABEL_FRAMEWORK , startHrtime , prettyHrtime ) ;
220- try {
221- frameworkResult = await frameworkCache . cleanCache ( ui5DataDir , onProgress ) ;
222- } finally {
223- finalise ( ) ;
224- }
225- }
164+ const frameworkResult = await frameworkCache . cleanCache ( ui5DataDir ) ;
226165 const buildResult = await CacheManager . cleanCache ( ui5DataDir ) ;
227166
228167 process . stderr . write ( "\n" ) ;
229168 if ( frameworkResult ) {
230- const detail = formatLibraryStats (
231- frameworkResult . libraryCount , frameworkResult . projectCount , frameworkResult . versionCount ) ;
169+ const detail = formatFrameworkStats ( frameworkResult . libraryCount , frameworkResult . versionCount ) ;
232170 process . stderr . write (
233171 `${ chalk . green ( "✓" ) } Removed ${ chalk . bold ( LABEL_FRAMEWORK ) } ` +
234172 ` (${ frameworkAbsPath } · ${ detail } )\n`
0 commit comments