From c824915f00c3d7a3b1f79b6c3cbe15e0b167dacf Mon Sep 17 00:00:00 2001 From: elrrrrrrr Date: Tue, 31 Oct 2023 01:23:51 +0800 Subject: [PATCH 1/5] feat: rapid bar --- package.json | 5 ++- packages/cli/lib/download_dependency.js | 13 +++--- packages/cli/lib/downloader.js | 10 ++++- packages/cli/lib/logger.js | 46 ++++++++++++++++++++++ packages/cli/lib/npm_fs/index.js | 9 +++++ packages/cli/lib/npm_fs/npm_fs_builder.js | 2 + packages/cli/lib/npm_fs/tnpm_fs_builder.js | 5 ++- packages/cli/lib/nydusd/fuse_mode.js | 6 ++- packages/cli/package.json | 1 + 9 files changed, 85 insertions(+), 12 deletions(-) create mode 100644 packages/cli/lib/logger.js diff --git a/package.json b/package.json index 8e67492..45dc9f3 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,6 @@ "version": "lerna version --conventional-commits --sign-git-commit --sign-git-tag --no-push --no-private" }, "devDependencies": { - "lerna": "^7.1.4", "@eggjs/tsconfig": "^1.0.0", "@types/mocha": "^8.2.0", "@types/node": "^18.16.3", @@ -38,6 +37,7 @@ "eslint-config-egg": "^12.0.0", "espower-typescript": "^9.0.2", "intelli-espower-loader": "^1.0.1", + "lerna": "^7.1.4", "mm": "^2.2.0", "mocha": "^8.2.1", "nock": "^13.0.9", @@ -52,5 +52,8 @@ }, "engines": { "node": ">=14.19.1" + }, + "dependencies": { + "cli-progress": "^3.12.0" } } diff --git a/packages/cli/lib/download_dependency.js b/packages/cli/lib/download_dependency.js index a807261..e8a8621 100644 --- a/packages/cli/lib/download_dependency.js +++ b/packages/cli/lib/download_dependency.js @@ -43,23 +43,19 @@ async function download(options) { const blobManager = new NpmBlobManager(); const entryListener = entryListenerFactory(blobManager); - console.time('[rapid] downloader new'); const downloader = new Downloader({ entryListener, productionMode: options.productionMode, }); - console.timeEnd('[rapid] downloader new'); - console.time('[rapid] downloader init'); await downloader.init(); - console.timeEnd('[rapid] downloader init'); + options.downloader = downloader; const depsTree = options.depsTree; - console.time('[rapid] parallel download time'); await downloader.download(depsTree); - console.log('[rapid] download finished'); const { tocMap, indices } = downloader.dumpdata; await downloader.shutdown(); + console.log('[rapid] download finished'); for (const [ blobId, tocIndex ] of Object.entries(tocMap)) { blobManager.addBlob(blobId, tocIndex); @@ -98,16 +94,19 @@ async function download(options) { } } } - console.timeEnd('[rapid] parallel download time'); console.time('[rapid] generate fs meta'); + + const npmFs = new NpmFs(blobManager, options); const allPkgs = await util.getAllPkgPaths(options.cwd, options.pkg); + await Promise.all(allPkgs.map(async pkgPath => { const { tarIndex } = await util.getWorkdir(options.cwd, pkgPath); const fsMeta = await npmFs.getFsMeta(depsTree, pkgPath); await fs.mkdir(path.dirname(tarIndex), { recursive: true }); await fs.writeFile(tarIndex, JSON.stringify(fsMeta), 'utf8'); })); + // FIXME atomic write await fs.writeFile(npmCacheConfigPath, JSON.stringify(tocMap), 'utf8'); await fs.writeFile(npmIndexConfigPath, JSON.stringify(indices), 'utf8'); diff --git a/packages/cli/lib/downloader.js b/packages/cli/lib/downloader.js index 281cb9b..560109e 100644 --- a/packages/cli/lib/downloader.js +++ b/packages/cli/lib/downloader.js @@ -3,6 +3,7 @@ const Util = require('./util'); const { tarBucketsDir, npmCacheConfigPath, npmIndexConfigPath } = require('./constants'); const os = require('node:os'); +const { Bar } = require('./logger'); const platform = os.platform(); const arch = os.arch(); @@ -47,7 +48,10 @@ class Downloader { httpConcurrentCount: this.httpConcurrentCount, downloadDir: tarBucketsDir, entryWhitelist: [ '*/package.json', '*/binding.gyp' ], - entryListener: this.entryListener, + entryListener: entry => { + this.bar.update(entry?.pkgName); + this.entryListener(entry); + }, downloadTimeout: this.downloadTimeout, tocPath: { map: npmCacheConfigPath, @@ -59,6 +63,10 @@ class Downloader { async download(pkgLockJson) { const tasks = this.createDownloadTask(pkgLockJson); console.log('[rapid] downloads %d packages', tasks.length); + this.bar = new Bar({ + type: 'download', + total: tasks.length, + }); await this.rapidDownloader.batchDownloads(tasks); } diff --git a/packages/cli/lib/logger.js b/packages/cli/lib/logger.js new file mode 100644 index 0000000..574829b --- /dev/null +++ b/packages/cli/lib/logger.js @@ -0,0 +1,46 @@ +const cliProgress = require('cli-progress'); + +class Bar { + constructor({ type, total }) { + this.multiBar = new cliProgress.MultiBar( + { + clearOnComplete: false, + hideCursor: true, + format: `[rapid] [{bar}] {percentage}% | ${type} | {status} | {message}`, + }, + cliProgress.Presets.shades_grey + ); + + this.startTime = Date.now(); + + // init + this.bar = this.multiBar.create(total, 0, { + status: 'Waiting', + warning: '', + message: '', + }); + + } + + update(current = '') { + + const { value, total } = this.bar; + if (value < total) { + this.bar.update(value + 1, { status: 'Running', message: current }); + } + + if (value >= total - 1) { + this.bar.update(total, { + status: 'Complete', + message: Date.now() - this.startTime + 'ms', + }); + this.stop(); + } + } + + stop() { + this.multiBar.stop(); + } +} + +exports.Bar = Bar; diff --git a/packages/cli/lib/npm_fs/index.js b/packages/cli/lib/npm_fs/index.js index 47bff1d..1a3e784 100644 --- a/packages/cli/lib/npm_fs/index.js +++ b/packages/cli/lib/npm_fs/index.js @@ -4,6 +4,7 @@ const assert = require('node:assert'); const NpmFsBuilder = require('./npm_fs_builder'); const TnpmFsBuilder = require('./tnpm_fs_builder'); const { NpmFsMode } = require('../constants'); +const { Bar } = require('../logger'); class NpmFs { /** @@ -15,10 +16,18 @@ class NpmFs { */ constructor(blobManager, options) { this.blobManager = blobManager; + this.bar = new Bar({ + type: 'FsMeta', + total: Object.keys(options.depsTree.packages).length, + }); + this.options = Object.assign({ uid: process.getuid(), gid: process.getgid(), mode: NpmFsMode.NPM, + entryListener: entry => { + this.bar.update(entry); + }, }, options); } diff --git a/packages/cli/lib/npm_fs/npm_fs_builder.js b/packages/cli/lib/npm_fs/npm_fs_builder.js index f4e70ec..a388fed 100644 --- a/packages/cli/lib/npm_fs/npm_fs_builder.js +++ b/packages/cli/lib/npm_fs/npm_fs_builder.js @@ -19,6 +19,7 @@ class NpmFsMetaBuilder { this.uid = options.uid; this.gid = options.gid; this.cwd = options.cwd; + this.entryListener = options.entryListener; this.productionMode = options.productionMode; // 项目直接依赖的 bin this.pkgBinSet = new Set(); @@ -29,6 +30,7 @@ class NpmFsMetaBuilder { await packageLock.load(); const packages = packageLock.packages; for (const [ pkgPath, pkgItem ] of Object.entries(packages)) { + this.entryListener?.(pkgPath); if (!pkgPath || !Util.validDep(pkgItem, this.productionMode)) continue; // npm alias or normal npm package const name = Util.getAliasPackageNameFromPackagePath(pkgPath, packages); diff --git a/packages/cli/lib/npm_fs/tnpm_fs_builder.js b/packages/cli/lib/npm_fs/tnpm_fs_builder.js index 57ed396..2bc17a7 100644 --- a/packages/cli/lib/npm_fs/tnpm_fs_builder.js +++ b/packages/cli/lib/npm_fs/tnpm_fs_builder.js @@ -15,7 +15,7 @@ class TnpmFsBuilder { */ constructor(blobManager, options) { this.blobManager = blobManager; - this.fsMeta = new FsMeta(); + this.fsMeta = new FsMeta(options.entryListener); this.uid = options.uid; this.gid = options.gid; this.productionMode = options.productionMode; @@ -25,7 +25,7 @@ class TnpmFsBuilder { this.projectVersions = new Map(); } - generateFsMeta(packageLockJson) { + generateFsMeta(packageLockJson, _, entryListener) { this.getProjectVersions(packageLockJson); this.getLatestVersions(packageLockJson); this.createRealPkgs(packageLockJson); @@ -34,6 +34,7 @@ class TnpmFsBuilder { const blobId = this.fsMeta.blobIds[0]; const packages = packageLockJson.packages; for (const [ pkgPath, pkgItem ] of Object.entries(packages)) { + entryListener?.(pkgItem); if (this.shouldSkipGenerate(pkgPath, pkgItem)) continue; const name = Util.getPackageNameFromPackagePath(pkgPath, packages); const version = pkgItem.version; diff --git a/packages/cli/lib/nydusd/fuse_mode.js b/packages/cli/lib/nydusd/fuse_mode.js index b275afd..7ad836c 100644 --- a/packages/cli/lib/nydusd/fuse_mode.js +++ b/packages/cli/lib/nydusd/fuse_mode.js @@ -17,6 +17,7 @@ const { listMountInfo, } = require('../util'); const nydusdApi = require('./nydusd_api'); +const { Bar } = require('../logger'); async function startNydusFs(cwd, pkg) { await Promise.all([ @@ -34,11 +35,14 @@ async function startNydusFs(cwd, pkg) { async function generateBootstrapFile(cwd, pkg) { console.time('[rapid] generate bootstrap'); const allPkgs = await getAllPkgPaths(cwd, pkg); + const bar = new Bar({ type: 'bootstrap', total: allPkgs.length }); await Promise.all(allPkgs.map(async pkgPath => { - const { bootstrap, tarIndex } = await getWorkdir(cwd, pkgPath); + const { bootstrap, tarIndex, nodeModulesDir } = await getWorkdir(cwd, pkgPath); await fs.mkdir(path.dirname(bootstrap), { recursive: true }); await execa.command(`${BOOTSTRAP_BIN} --stargz-config-path=${tarIndex} --stargz-dir=${tarBucketsDir} --bootstrap=${bootstrap}`); + bar.update(nodeModulesDir); })); + console.log('\n'); console.timeEnd('[rapid] generate bootstrap'); } diff --git a/packages/cli/package.json b/packages/cli/package.json index 562595d..c7cd45c 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -17,6 +17,7 @@ "await-event": "^2.1.0", "binary-mirror-config": "^2.5.0", "chalk": "^4.0.0", + "cli-progress": "^3.12.0", "execa": "^5.1.1", "inquirer": "^8.2.6", "ms": "^0.7.1", From 2c3cd87619c8755c0015204c98c1a9f3b106b11a Mon Sep 17 00:00:00 2001 From: elrrrrrrr Date: Tue, 31 Oct 2023 10:36:33 +0800 Subject: [PATCH 2/5] feat: add mount bars --- packages/cli/lib/download_dependency.js | 6 ++-- packages/cli/lib/logger.js | 10 ++++++- packages/cli/lib/nydusd/fuse_mode.js | 38 ++++++++++++++++--------- 3 files changed, 37 insertions(+), 17 deletions(-) diff --git a/packages/cli/lib/download_dependency.js b/packages/cli/lib/download_dependency.js index e8a8621..256af7c 100644 --- a/packages/cli/lib/download_dependency.js +++ b/packages/cli/lib/download_dependency.js @@ -94,7 +94,9 @@ async function download(options) { } } } - console.time('[rapid] generate fs meta'); + // console.time('[rapid] generate fs meta'); + + console.log('[rapid] generate fs meta'); const npmFs = new NpmFs(blobManager, options); @@ -110,7 +112,7 @@ async function download(options) { // FIXME atomic write await fs.writeFile(npmCacheConfigPath, JSON.stringify(tocMap), 'utf8'); await fs.writeFile(npmIndexConfigPath, JSON.stringify(indices), 'utf8'); - console.timeEnd('[rapid] generate fs meta'); + // console.timeEnd('[rapid] generate fs meta'); return { depsTree, }; diff --git a/packages/cli/lib/logger.js b/packages/cli/lib/logger.js index 574829b..5ce1edc 100644 --- a/packages/cli/lib/logger.js +++ b/packages/cli/lib/logger.js @@ -1,12 +1,20 @@ const cliProgress = require('cli-progress'); +function padCenter(str, length, char = ' ') { + const padLength = length - str.length; + const padLeft = Math.floor(padLength / 2); + const padRight = padLength - padLeft; + return char.repeat(padLeft) + str + char.repeat(padRight); +} + class Bar { constructor({ type, total }) { + const title = padCenter(type, 11); this.multiBar = new cliProgress.MultiBar( { clearOnComplete: false, hideCursor: true, - format: `[rapid] [{bar}] {percentage}% | ${type} | {status} | {message}`, + format: `[rapid] [{bar}] {percentage}% |${title}| {status} | {message}`, }, cliProgress.Presets.shades_grey ); diff --git a/packages/cli/lib/nydusd/fuse_mode.js b/packages/cli/lib/nydusd/fuse_mode.js index 7ad836c..a6a0928 100644 --- a/packages/cli/lib/nydusd/fuse_mode.js +++ b/packages/cli/lib/nydusd/fuse_mode.js @@ -20,20 +20,20 @@ const nydusdApi = require('./nydusd_api'); const { Bar } = require('../logger'); async function startNydusFs(cwd, pkg) { - await Promise.all([ - nydusdApi.initDaemon(), - generateBootstrapFile(cwd, pkg), - ]); + await nydusdApi.initDaemon(); + console.log('[rapid] generate bootstrap'); + await generateBootstrapFile(cwd, pkg); + + console.log('[rapid] mount nydusd'); await mountNydus(cwd, pkg); - console.time('[rapid] mount overlay'); + console.log('[rapid] mount overlay'); await mountOverlay(cwd, pkg); - console.timeEnd('[rapid] mount overlay'); } async function generateBootstrapFile(cwd, pkg) { - console.time('[rapid] generate bootstrap'); + // console.time('[rapid] generate bootstrap'); const allPkgs = await getAllPkgPaths(cwd, pkg); const bar = new Bar({ type: 'bootstrap', total: allPkgs.length }); await Promise.all(allPkgs.map(async pkgPath => { @@ -42,24 +42,33 @@ async function generateBootstrapFile(cwd, pkg) { await execa.command(`${BOOTSTRAP_BIN} --stargz-config-path=${tarIndex} --stargz-dir=${tarBucketsDir} --bootstrap=${bootstrap}`); bar.update(nodeModulesDir); })); - console.log('\n'); - console.timeEnd('[rapid] generate bootstrap'); + // console.timeEnd('[rapid] generate bootstrap'); } async function mountNydus(cwd, pkg) { const allPkgs = await getAllPkgPaths(cwd, pkg); + const bar = new Bar({ + type: 'mount', + total: allPkgs.length, + }); + // 需要串行 mount,并发创建时 nydusd 会出现问题 for (const pkgPath of allPkgs) { const { dirname, bootstrap } = await getWorkdir(cwd, pkgPath); - console.time(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`); + // console.time(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`); await nydusdApi.mount(`/${dirname}`, cwd, bootstrap); - console.timeEnd(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`); + bar.update(dirname); + // console.timeEnd(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`); } } async function mountOverlay(cwd, pkg) { const allPkgs = await getAllPkgPaths(cwd, pkg); + const bar = new Bar({ + type: 'overlay', + total: allPkgs.length, + }); await Promise.all(allPkgs.map(async pkgPath => { const { upper, @@ -106,10 +115,11 @@ ${nodeModulesDir}`); ${upper}=RW:${mnt}=RO \ ${nodeModulesDir}`; } - console.info('[rapid] mountOverlay: `%s`', shScript); - console.time(`[rapid] overlay ${overlay} mounted.`); + // console.info('[rapid] mountOverlay: `%s`', shScript); + // console.time(`[rapid] overlay ${overlay} mounted.`); await execa.command(shScript); - console.timeEnd(`[rapid] overlay ${overlay} mounted.`); + bar.update(nodeModulesDir); + // console.timeEnd(`[rapid] overlay ${overlay} mounted.`); })); } From f1d68ff514c58c392a59d164afc5fb5134ae5b40 Mon Sep 17 00:00:00 2001 From: elrrrrrrr Date: Tue, 31 Oct 2023 10:46:56 +0800 Subject: [PATCH 3/5] fix: clean not work --- packages/cli/lib/index.js | 3 ++- packages/cli/lib/nydusd/fuse_mode.js | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/cli/lib/index.js b/packages/cli/lib/index.js index d738541..8ab1191 100644 --- a/packages/cli/lib/index.js +++ b/packages/cli/lib/index.js @@ -75,7 +75,8 @@ exports.clean = async function clean({ nydusMode = NYDUS_TYPE.FUSE, cwd, force, return; } if (!pkg) { - pkg = await util.readPkgJSON(cwd); + const pkgRes = await util.readPkgJSON(cwd); + pkg = pkgRes.pkg; } await nydusd.endNydusFs(nydusMode, cwd, pkg, force); }; diff --git a/packages/cli/lib/nydusd/fuse_mode.js b/packages/cli/lib/nydusd/fuse_mode.js index a6a0928..f1a3da4 100644 --- a/packages/cli/lib/nydusd/fuse_mode.js +++ b/packages/cli/lib/nydusd/fuse_mode.js @@ -123,7 +123,7 @@ ${nodeModulesDir}`; })); } -async function endNydusFs(cwd, pkg, force = false) { +async function endNydusFs(cwd, pkg, force = true) { const allPkgs = await getAllPkgPaths(cwd, pkg); const umountCmd = force ? 'umount -f' : 'umount'; await Promise.all(allPkgs.map(async pkgPath => { @@ -167,7 +167,7 @@ async function endNydusFs(cwd, pkg, force = false) { }, fallback: force ? async () => { - await execa.command(`hdiutil detach -force ${overlay}`); + await execa.command(`umount -f ${overlay}`); } : undefined, }); From 282ade393a83b77b51c02a03cb84ed119e2b65ca Mon Sep 17 00:00:00 2001 From: elrrrrrrr Date: Tue, 31 Oct 2023 11:34:42 +0800 Subject: [PATCH 4/5] feat: add processing when download --- package.json | 5 +---- packages/cli/lib/download_dependency.js | 2 -- packages/cli/lib/downloader.js | 2 ++ packages/cli/lib/logger.js | 22 +++++++++++++++------- packages/cli/lib/npm_fs/index.js | 15 +++++++-------- packages/cli/lib/npm_fs/npm_fs_builder.js | 4 ++-- packages/cli/lib/npm_fs/tnpm_fs_builder.js | 2 +- packages/cli/lib/nydusd/fuse_mode.js | 8 +------- 8 files changed, 29 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 45dc9f3..8e67492 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "version": "lerna version --conventional-commits --sign-git-commit --sign-git-tag --no-push --no-private" }, "devDependencies": { + "lerna": "^7.1.4", "@eggjs/tsconfig": "^1.0.0", "@types/mocha": "^8.2.0", "@types/node": "^18.16.3", @@ -37,7 +38,6 @@ "eslint-config-egg": "^12.0.0", "espower-typescript": "^9.0.2", "intelli-espower-loader": "^1.0.1", - "lerna": "^7.1.4", "mm": "^2.2.0", "mocha": "^8.2.1", "nock": "^13.0.9", @@ -52,8 +52,5 @@ }, "engines": { "node": ">=14.19.1" - }, - "dependencies": { - "cli-progress": "^3.12.0" } } diff --git a/packages/cli/lib/download_dependency.js b/packages/cli/lib/download_dependency.js index 256af7c..4e790d8 100644 --- a/packages/cli/lib/download_dependency.js +++ b/packages/cli/lib/download_dependency.js @@ -94,7 +94,6 @@ async function download(options) { } } } - // console.time('[rapid] generate fs meta'); console.log('[rapid] generate fs meta'); @@ -112,7 +111,6 @@ async function download(options) { // FIXME atomic write await fs.writeFile(npmCacheConfigPath, JSON.stringify(tocMap), 'utf8'); await fs.writeFile(npmIndexConfigPath, JSON.stringify(indices), 'utf8'); - // console.timeEnd('[rapid] generate fs meta'); return { depsTree, }; diff --git a/packages/cli/lib/downloader.js b/packages/cli/lib/downloader.js index 560109e..7827af7 100644 --- a/packages/cli/lib/downloader.js +++ b/packages/cli/lib/downloader.js @@ -39,6 +39,7 @@ class Downloader { async shutdown() { if (!this.rapidDownloader) return; await this.rapidDownloader.shutdown(); + this.bar.stop(); } createRapidDownloader() { @@ -66,6 +67,7 @@ class Downloader { this.bar = new Bar({ type: 'download', total: tasks.length, + autoFinish: false, }); await this.rapidDownloader.batchDownloads(tasks); } diff --git a/packages/cli/lib/logger.js b/packages/cli/lib/logger.js index 5ce1edc..b415730 100644 --- a/packages/cli/lib/logger.js +++ b/packages/cli/lib/logger.js @@ -1,5 +1,7 @@ const cliProgress = require('cli-progress'); +const MAX_TITLE_LENGTH = 11; + function padCenter(str, length, char = ' ') { const padLength = length - str.length; const padLeft = Math.floor(padLength / 2); @@ -8,8 +10,8 @@ function padCenter(str, length, char = ' ') { } class Bar { - constructor({ type, total }) { - const title = padCenter(type, 11); + constructor({ type, total, autoFinish = true }) { + const title = padCenter(type, MAX_TITLE_LENGTH); this.multiBar = new cliProgress.MultiBar( { clearOnComplete: false, @@ -20,6 +22,7 @@ class Bar { ); this.startTime = Date.now(); + this.autoFinish = autoFinish; // init this.bar = this.multiBar.create(total, 0, { @@ -38,15 +41,20 @@ class Bar { } if (value >= total - 1) { - this.bar.update(total, { - status: 'Complete', - message: Date.now() - this.startTime + 'ms', - }); - this.stop(); + if (this.autoFinish) { + this.stop(); + } else { + this.bar.update(total - 1, { status: 'Processing', message: 'Processing...' }); + } } } stop() { + const { total } = this.bar; + this.bar.update(total, { + status: 'Complete', + message: Date.now() - this.startTime + 'ms', + }); this.multiBar.stop(); } } diff --git a/packages/cli/lib/npm_fs/index.js b/packages/cli/lib/npm_fs/index.js index 1a3e784..b77ca13 100644 --- a/packages/cli/lib/npm_fs/index.js +++ b/packages/cli/lib/npm_fs/index.js @@ -16,18 +16,11 @@ class NpmFs { */ constructor(blobManager, options) { this.blobManager = blobManager; - this.bar = new Bar({ - type: 'FsMeta', - total: Object.keys(options.depsTree.packages).length, - }); this.options = Object.assign({ uid: process.getuid(), gid: process.getgid(), mode: NpmFsMode.NPM, - entryListener: entry => { - this.bar.update(entry); - }, }, options); } @@ -36,9 +29,15 @@ class NpmFs { } async getFsMeta(pkgLockJson, pkgPath = '') { + this.bar = new Bar({ + type: 'fs meta', + total: Object.keys(pkgLockJson.packages).length, + }); const builderClazz = this._getFsMetaBuilder(); const builder = new builderClazz(this.blobManager, this.options); - return await builder.generateFsMeta(pkgLockJson, pkgPath); + return await builder.generateFsMeta(pkgLockJson, pkgPath, entryName => { + this.bar.update(entryName); + }); } _getFsMetaBuilder() { diff --git a/packages/cli/lib/npm_fs/npm_fs_builder.js b/packages/cli/lib/npm_fs/npm_fs_builder.js index a388fed..bac5a8c 100644 --- a/packages/cli/lib/npm_fs/npm_fs_builder.js +++ b/packages/cli/lib/npm_fs/npm_fs_builder.js @@ -25,12 +25,12 @@ class NpmFsMetaBuilder { this.pkgBinSet = new Set(); } - async generateFsMeta(packageLockJson, currentPkgPath) { + async generateFsMeta(packageLockJson, currentPkgPath, entryListener) { const packageLock = new PackageLock({ cwd: this.cwd, packageLockJson }); await packageLock.load(); const packages = packageLock.packages; for (const [ pkgPath, pkgItem ] of Object.entries(packages)) { - this.entryListener?.(pkgPath); + entryListener?.(pkgPath); if (!pkgPath || !Util.validDep(pkgItem, this.productionMode)) continue; // npm alias or normal npm package const name = Util.getAliasPackageNameFromPackagePath(pkgPath, packages); diff --git a/packages/cli/lib/npm_fs/tnpm_fs_builder.js b/packages/cli/lib/npm_fs/tnpm_fs_builder.js index 2bc17a7..08d18a1 100644 --- a/packages/cli/lib/npm_fs/tnpm_fs_builder.js +++ b/packages/cli/lib/npm_fs/tnpm_fs_builder.js @@ -34,7 +34,7 @@ class TnpmFsBuilder { const blobId = this.fsMeta.blobIds[0]; const packages = packageLockJson.packages; for (const [ pkgPath, pkgItem ] of Object.entries(packages)) { - entryListener?.(pkgItem); + entryListener?.(pkgPath); if (this.shouldSkipGenerate(pkgPath, pkgItem)) continue; const name = Util.getPackageNameFromPackagePath(pkgPath, packages); const version = pkgItem.version; diff --git a/packages/cli/lib/nydusd/fuse_mode.js b/packages/cli/lib/nydusd/fuse_mode.js index f1a3da4..06b6595 100644 --- a/packages/cli/lib/nydusd/fuse_mode.js +++ b/packages/cli/lib/nydusd/fuse_mode.js @@ -28,12 +28,11 @@ async function startNydusFs(cwd, pkg) { console.log('[rapid] mount nydusd'); await mountNydus(cwd, pkg); - console.log('[rapid] mount overlay'); + console.log('[rapid] mount overlay, it may take a few seconds'); await mountOverlay(cwd, pkg); } async function generateBootstrapFile(cwd, pkg) { - // console.time('[rapid] generate bootstrap'); const allPkgs = await getAllPkgPaths(cwd, pkg); const bar = new Bar({ type: 'bootstrap', total: allPkgs.length }); await Promise.all(allPkgs.map(async pkgPath => { @@ -42,7 +41,6 @@ async function generateBootstrapFile(cwd, pkg) { await execa.command(`${BOOTSTRAP_BIN} --stargz-config-path=${tarIndex} --stargz-dir=${tarBucketsDir} --bootstrap=${bootstrap}`); bar.update(nodeModulesDir); })); - // console.timeEnd('[rapid] generate bootstrap'); } async function mountNydus(cwd, pkg) { @@ -56,10 +54,8 @@ async function mountNydus(cwd, pkg) { // 需要串行 mount,并发创建时 nydusd 会出现问题 for (const pkgPath of allPkgs) { const { dirname, bootstrap } = await getWorkdir(cwd, pkgPath); - // console.time(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`); await nydusdApi.mount(`/${dirname}`, cwd, bootstrap); bar.update(dirname); - // console.timeEnd(`[rapid] mount '/${dirname}' to nydusd daemon using socket api`); } } @@ -116,10 +112,8 @@ ${upper}=RW:${mnt}=RO \ ${nodeModulesDir}`; } // console.info('[rapid] mountOverlay: `%s`', shScript); - // console.time(`[rapid] overlay ${overlay} mounted.`); await execa.command(shScript); bar.update(nodeModulesDir); - // console.timeEnd(`[rapid] overlay ${overlay} mounted.`); })); } From f2aa36e9afefaabe902bfc30c1c71a43112d61c5 Mon Sep 17 00:00:00 2001 From: elrrrrrrr Date: Tue, 31 Oct 2023 13:57:53 +0800 Subject: [PATCH 5/5] feat: ignore !isTTY --- packages/cli/lib/logger.js | 37 ++++++++++++++++++---------- packages/cli/lib/npm_fs/index.js | 4 ++- packages/cli/lib/nydusd/fuse_mode.js | 3 +++ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/packages/cli/lib/logger.js b/packages/cli/lib/logger.js index b415730..6b35bab 100644 --- a/packages/cli/lib/logger.js +++ b/packages/cli/lib/logger.js @@ -10,8 +10,10 @@ function padCenter(str, length, char = ' ') { } class Bar { - constructor({ type, total, autoFinish = true }) { + constructor({ type, total }) { const title = padCenter(type, MAX_TITLE_LENGTH); + this.type = type; + this.total = total; this.multiBar = new cliProgress.MultiBar( { clearOnComplete: false, @@ -22,40 +24,49 @@ class Bar { ); this.startTime = Date.now(); - this.autoFinish = autoFinish; + this.isTTY = process.stdout.isTTY; // init - this.bar = this.multiBar.create(total, 0, { - status: 'Waiting', - warning: '', - message: '', - }); + if (this.isTTY) { + this.bar = this.multiBar.create(total, 1, { + status: 'Running', + warning: '', + message: '', + }); + } } update(current = '') { + if (!this.isTTY) { + return; + } + const { value, total } = this.bar; if (value < total) { - this.bar.update(value + 1, { status: 'Running', message: current }); + this.isTTY && this.bar.update(value + 1, { status: 'Running', message: current }); } if (value >= total - 1) { - if (this.autoFinish) { - this.stop(); - } else { - this.bar.update(total - 1, { status: 'Processing', message: 'Processing...' }); - } + this.isTTY && this.bar.update(total - 1, { status: 'Processing', message: 'Processing...' }); } } stop() { + if (!this.isTTY) { + console.log('[rapid] %s complete, %dms', this.type, Date.now() - this.startTime); + return; + } + const { total } = this.bar; this.bar.update(total, { status: 'Complete', message: Date.now() - this.startTime + 'ms', }); + this.multiBar.stop(); + } } diff --git a/packages/cli/lib/npm_fs/index.js b/packages/cli/lib/npm_fs/index.js index b77ca13..3626b29 100644 --- a/packages/cli/lib/npm_fs/index.js +++ b/packages/cli/lib/npm_fs/index.js @@ -35,9 +35,11 @@ class NpmFs { }); const builderClazz = this._getFsMetaBuilder(); const builder = new builderClazz(this.blobManager, this.options); - return await builder.generateFsMeta(pkgLockJson, pkgPath, entryName => { + const res = await builder.generateFsMeta(pkgLockJson, pkgPath, entryName => { this.bar.update(entryName); }); + this.bar.stop(); + return res; } _getFsMetaBuilder() { diff --git a/packages/cli/lib/nydusd/fuse_mode.js b/packages/cli/lib/nydusd/fuse_mode.js index 06b6595..cc38f5b 100644 --- a/packages/cli/lib/nydusd/fuse_mode.js +++ b/packages/cli/lib/nydusd/fuse_mode.js @@ -41,6 +41,7 @@ async function generateBootstrapFile(cwd, pkg) { await execa.command(`${BOOTSTRAP_BIN} --stargz-config-path=${tarIndex} --stargz-dir=${tarBucketsDir} --bootstrap=${bootstrap}`); bar.update(nodeModulesDir); })); + bar.stop(); } async function mountNydus(cwd, pkg) { @@ -57,6 +58,7 @@ async function mountNydus(cwd, pkg) { await nydusdApi.mount(`/${dirname}`, cwd, bootstrap); bar.update(dirname); } + bar.stop(); } async function mountOverlay(cwd, pkg) { @@ -115,6 +117,7 @@ ${nodeModulesDir}`; await execa.command(shScript); bar.update(nodeModulesDir); })); + bar.stop(); } async function endNydusFs(cwd, pkg, force = true) {