Skip to content
Open

Dev #74

Show file tree
Hide file tree
Changes from all commits
Commits
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
17 changes: 17 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

36 changes: 36 additions & 0 deletions src/cli/interactive.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
import readline from "readline";
const interactive = () => {
// Write your code here
// Use readline module for interactive CLI
// Support commands: uptime, cwd, date, exit
// Handle Ctrl+C and unknown commands

const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: "> ",
});
console.log("Welcome! Type a command");
rl.prompt();

rl.on("line", (line) => {
const command = line.trim();

switch (command) {
case "uptime":
console.log(`Uptime: ${process.uptime().toFixed(2)}s`);
break;
case "cwd":
console.log(process.cwd());
break;
case "date":
console.log(new Date().toISOString());
break;
case "exit":
rl.close();
return;
default:
console.log("Unknown command");
}

rl.prompt();
});
rl.on("close", () => {
console.log("Goodbye!");
process.exit(0);
});
};

interactive();
42 changes: 42 additions & 0 deletions src/cli/progress.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,48 @@ const progress = () => {
// Simulate progress bar from 0% to 100% over ~5 seconds
// Update in place using \r every 100ms
// Format: [████████████████████ ] 67%
const args = process.argv;

const durationIndex = args.indexOf("--duration");
const duration =
durationIndex !== -1 ? Number(args[durationIndex + 1]) : 5000;

const intervalIndex = args.indexOf("--interval");
const interval = intervalIndex !== -1 ? Number(args[intervalIndex + 1]) : 100;

const lengthlIndex = args.indexOf("--length");
const length = lengthlIndex !== -1 ? Number(args[lengthlIndex + 1]) : 30;

const colorIndex = args.indexOf("--color");
const color = colorIndex !== -1 ? args[colorIndex + 1] : "";
console.log(color);

const steps = Math.floor(duration / interval);

let currentStep = 0;

const timer = setInterval(() => {
currentStep++;

const percent = Math.floor((currentStep / steps) * 100);

const filled = Math.floor((percent / 100) * length);

const bar =
"[" +
"█".repeat(filled) +
" ".repeat(length - filled) +
"] " +
percent +
"%";

process.stdout.write("\r" + bar);

if (currentStep >= steps) {
clearInterval(timer);
console.log("\nDone!");
}
}, interval);
};

progress();
37 changes: 37 additions & 0 deletions src/fs/findByExt.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,44 @@
import path from "path";
import fs from "fs/promises";

const findByExt = async () => {
// Write your code here
// Recursively find all files with specific extension
// Parse --ext CLI argument (default: .txt)

try {
await fs.stat("./workspace");
} catch (e) {
throw new Error("FS operation failed");
}
console.log(process.argv);
let files = [];
const extIndex = process.argv.indexOf("--ext");
const ext = extIndex !== -1 ? process.argv[extIndex + 1] : "txt";
// console.log(extIndex);
// console.log(ext);

const scan = async (currPath) => {
const entries = await fs.readdir(currPath, { withFileTypes: true });
// console.log(entries);
for (const item of entries) {
const fullPath = path.join(currPath, item.name);
const relativePath = path
.relative("./workspace", fullPath)
.replace(/\\/g, "/");

if (item.isDirectory()) {
await scan(fullPath); // рекурсивно сканируем
}

if (item.isFile() && path.extname(item.name).slice(1) === ext) {
files.push(relativePath); // сохраняем путь файла с нужным расширением
}
}
};

await scan("./workspace");
files.sort().forEach((f) => console.log(f));
};

await findByExt();
29 changes: 29 additions & 0 deletions src/fs/merge.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,37 @@
import fs from "fs/promises";
import path from "path";

const merge = async () => {
// Write your code here
// Default: read all .txt files from workspace/parts in alphabetical order
// Optional: support --files filename1,filename2,... to merge specific files in provided order
// Concatenate content and write to workspace/merged.txt
let filesToMerge = [];
let result = "";
const folderPath = "./workspace/parts";
try {
await fs.access(folderPath);

const extIndex = process.argv.indexOf("--files");
if (extIndex !== -1) {
filesToMerge = process.argv[extIndex + 1].split(",");
} else {
let entries = await fs.readdir(folderPath, { withFileTypes: true });

let step1 = entries.filter((e) => e.isFile() && e.name.endsWith(".txt"));
let step2 = step1.map((e) => e.name);
filesToMerge = step2.sort();
}
if (filesToMerge.length === 0) throw new Error();
for (const file of filesToMerge) {
const entry = await fs.readFile(path.join(folderPath, file), "utf8");
result += entry;
console.log(result);
}
await fs.writeFile("./workspace/merged.txt", result);
} catch {
throw new Error("FS operation failed");
}
};

await merge();
36 changes: 36 additions & 0 deletions src/fs/restore.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,44 @@
import path from "path";
import fs from "fs/promises";

const restore = async () => {
// Write your code here
// Read snapshot.json
// Treat snapshot.rootPath as metadata only
// Recreate directory/file structure in workspace_restored

try {
await fs.stat("./snapshot.json");
} catch {
throw new Error("FS operation failed");
}

try {
await fs.stat("./workspace_restored");
// throw new Error("FS operation failed");
} catch (e) {
if (e.message === "FS operation failed") {
throw e;
}
await fs.mkdir("./workspace_restored");
}

try {
const data = await fs.readFile("./snapshot.json", "utf-8");
const snapshot = JSON.parse(data);
for (const item of snapshot.entries) {
const filePath = path.join("./workspace_restored", item.path);
console.log(filePath);
if (item.type === "directory") {
await fs.mkdir(filePath, { recursive: true });
}
if (item.type === "file") {
await fs.writeFile(filePath, item.content, "base64");
}
}
} catch (e) {
console.log(e);
}
};

await restore();
73 changes: 68 additions & 5 deletions src/fs/snapshot.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,72 @@
import path from "path";
import fs from "fs/promises";

import { fileURLToPath } from "url";

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

const snapshot = async () => {
// Write your code here
// Recursively scan workspace directory
// Write snapshot.json with:
// - rootPath: absolute path to workspace
// - entries: flat array of relative paths and metadata
const workspacePath = path.join(__dirname, "workspace");
const stats = await fs.stat(workspacePath);
const rootPath = path.resolve(workspacePath);
if (!stats.isDirectory()) {
throw new Error("FS operation failed");
}

const entries = [];

const scan = async (currentPath) => {
try {
let data = await fs.readdir(currentPath, { withFileTypes: true });
for (const item of data) {
const fullPath = path.join(currentPath, item.name);
const relativePath = path.relative(rootPath, fullPath);

if (item.isDirectory()) {
console.log("DIR:", item.name);
entries.push({
path: relativePath,
type: "directory",
});
console.log(entries);
await scan(fullPath);
}
if (item.isFile()) {
const buffer = await fs.readFile(fullPath);
const size = buffer.length;
const content = buffer.toString("base64");
console.log("FILE:", item.name);
entries.push({
path: relativePath,
type: "file",
size,
content,
});
}
}
} catch (err) {
console.log(err);
}

// console.log(path.basename());
// const workspacePath = path.join(process.cwd(), "home");
// Write your code here
// Recursively scan workspace directory
// Write snapshot.json with:
// - rootPath: absolute path to workspace
// - entries: flat array of relative paths and metadata
};

await scan(workspacePath);
const result = {
rootPath,
entries,
};
console.log(result);
const snapshotPath = path.join(path.dirname(workspacePath), "snapshot.json");

await fs.writeFile(snapshotPath, JSON.stringify(result, null, 2));
};

await snapshot();