diff --git a/src/cli/interactive.js b/src/cli/interactive.js index d0e3e0d9..145e5d92 100644 --- a/src/cli/interactive.js +++ b/src/cli/interactive.js @@ -1,8 +1,37 @@ +import readline from 'readline'; + +const rl = readline.createInterface({ + input: process.stdin, + output: process.stdoutdate +}); + +const commands = { + uptime: () => process.stdout.write(`${process.uptime()}\n`), + cwd: () => process.stdout.write(`${process.cwd()}\n`), + date: () => process.stdout.write(`${new Date()}\n`), + exit: () => { + process.stdout.write('\nGoodbye!\n'); + rl.close(); + process.exit(); + }, +}; + const interactive = () => { - // Write your code here - // Use readline module for interactive CLI - // Support commands: uptime, cwd, date, exit - // Handle Ctrl+C and unknown commands + rl.question('> ', (answer) => { + if (commands[answer]) { + commands[answer](); + } else { + process.stdout.write(`Unknown command\n`); + } + if (answer !== 'exit') { + interactive(); + } + }); }; +rl.on('SIGINT', () => { + process.stdout.write('\nGoodbye!\n'); + process.exit(); +}); + interactive(); diff --git a/src/cli/progress.js b/src/cli/progress.js index 3e060763..f4c44f7b 100644 --- a/src/cli/progress.js +++ b/src/cli/progress.js @@ -1,8 +1,35 @@ +const args = process.argv.slice(2); + +const getArg = (name) => { + const idx = args.indexOf(`--${name}`); + return idx !== -1 ? args[idx + 1] : undefined; +}; + +const duration = parseInt(getArg('duration') ?? '5000'); +const interval = parseInt(getArg('interval') ?? '100'); +const length = parseInt(getArg('length') ?? '30'); + +const printBar = (percent) => { + const filled = Math.floor(length * percent / 100); + const empty = length - filled; + const bar = '█'.repeat(filled) + '░'.repeat(empty); + process.stdout.write(`\r[${bar}] ${percent}%`); +}; + const progress = () => { - // Write your code here - // Simulate progress bar from 0% to 100% over ~5 seconds - // Update in place using \r every 100ms - // Format: [████████████████████ ] 67% + const steps = Math.floor(duration / interval); + const stepPercent = 100 / steps; + let elapsed = 0; + + const intervalId = setInterval(() => { + elapsed++; + const percent = Math.min(Math.round(elapsed * stepPercent), 100); + printBar(percent); + if (percent >= 100) { + clearInterval(intervalId); + process.stdout.write('\nDone!\n'); + } + }, 100); }; progress(); diff --git a/src/hash/verify.js b/src/hash/verify.js index 7f1e8961..1400086a 100644 --- a/src/hash/verify.js +++ b/src/hash/verify.js @@ -1,8 +1,33 @@ -const verify = async () => { - // Write your code here - // Read checksums.json - // Calculate SHA256 hash using Streams API - // Print result: filename — OK/FAIL +import crypto from 'node:crypto'; +import fs from 'node:fs'; +import { pipeline } from 'node:stream/promises'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +export const verify = async () => { + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + const file = path.join(__dirname, 'checksums.json'); + if (!fs.existsSync(file)) { + throw new Error('FS operation failed'); + } + + const checksums = JSON.parse(fs.readFileSync(file, 'utf8')); + + for (const [filename, storedHash] of Object.entries(checksums)) { + const relativePath = path.join(__dirname, filename); + if (!fs.existsSync(relativePath)) { + throw new Error('FS operation failed'); + } + + const stream = fs.createReadStream(relativePath); + const hash = crypto.createHash('sha256'); + + await pipeline(stream, hash); + + const result = hash.digest('hex'); + const status = result === storedHash ? 'OK' : 'FAIL'; + console.log(`${filename} — ${status}`); + } }; await verify();