-
-
Notifications
You must be signed in to change notification settings - Fork 42
London|25-SDC-NOV| FATMA DEGIRMENCI | Sprint 3|IMPLEMENT_SHELL_TOOLS #272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 3 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| program | ||
| .name("cat command") | ||
| .description("create cat command") | ||
| .option("-n", "Number all lines") | ||
| .option("-b", "Number non-empty lines") | ||
| .argument("<paths...>", "File paths"); | ||
|
|
||
| program.parse(); | ||
| const paths = program.args; | ||
| const number = program.opts().n; | ||
| const nonEmptyLine = program.opts().b; | ||
|
|
||
| let lineNumber = 1; | ||
|
|
||
| for (const path of paths) { | ||
| try { | ||
| const read = await fs.readFile(path, "utf-8"); | ||
| const lines = read.split("\n"); | ||
| for (let i of lines) { | ||
| if (number) { | ||
| console.log(`${String(lineNumber).padStart(6, " ")} ${i}`); | ||
| lineNumber++; | ||
| } else if (nonEmptyLine) { | ||
| if (i.trim() !== "") { | ||
| console.log(`${String(lineNumber).padStart(6, " ")} ${i}`); | ||
| lineNumber++; | ||
| } else { | ||
| console.log(i); | ||
| } | ||
| } else { | ||
| console.log(i); | ||
| } | ||
| } | ||
| } catch (err) { | ||
| console.error(`File could not read: ${path}`); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| program | ||
| .name("ls command") | ||
| .description("create ls command") | ||
| .option("-1", "One entry per line") | ||
| .option("-a", "Show all files including hidden") | ||
| .argument("[paths...]", "File paths"); | ||
|
|
||
| program.parse(); | ||
|
|
||
| const opts = program.opts(); | ||
| const paths = program.args.length > 0 ? program.args : ["."]; | ||
| const onePerLine = opts["1"]; | ||
| const showAll = opts.a; | ||
|
|
||
| for (const targetPath of paths) { | ||
| try { | ||
| let files = await fs.readdir(targetPath); | ||
|
|
||
| if (!showAll) { | ||
| files = files.filter((f) => !f.startsWith(".")); | ||
| } | ||
|
|
||
|
|
||
| if (paths.length > 1) { | ||
| console.log(`${targetPath}:`); | ||
| } | ||
|
|
||
| if (onePerLine) { | ||
| for (const f of files) console.log(f); | ||
| } else { | ||
| console.log(files.join(" ")); | ||
| } | ||
|
|
||
| if (paths.length > 1) { | ||
| console.log(); | ||
| } | ||
| } catch (err) { | ||
| console.error(`ls: cannot access '${targetPath}': ${err.message}`); | ||
| } | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "name": "implement-shell-tools", | ||
| "version": "1.0.0", | ||
| "description": "Your task is to re-implement shell tools you have used.", | ||
| "main": "index.js", | ||
| "type": "module", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "dependencies": { | ||
| "commander": "^14.0.2" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,53 @@ | ||
|
|
||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| program | ||
| .option("-l", "Print only the line count") | ||
| .option("-w", "Print only the word count") | ||
| .option("-c", "Print only the byte count") | ||
| .argument("<paths...>", "One or more file paths"); | ||
|
|
||
| program.parse(); | ||
|
|
||
| const opts = program.opts(); | ||
| const paths = program.args; | ||
|
|
||
| async function wcFile(path) { | ||
| const content = await fs.readFile(path, "utf8"); | ||
|
|
||
| const lines = content.split("\n").length; | ||
| const words = content.trim().split(/\s+/).filter(Boolean).length; | ||
| const bytes = Buffer.byteLength(content, "utf8"); | ||
|
|
||
| return { lines, words, bytes }; | ||
| } | ||
|
|
||
| function formatOutput(counts, filename, opts) { | ||
| if (opts.l) return `${counts.lines} ${filename}`; | ||
| if (opts.w) return `${counts.words} ${filename}`; | ||
| if (opts.c) return `${counts.bytes} ${filename}`; | ||
|
|
||
| return `${counts.lines} ${counts.words} ${counts.bytes} ${filename}`; | ||
|
||
| } | ||
|
|
||
| async function main() { | ||
| let total = { lines: 0, words: 0, bytes: 0 }; | ||
| let multipleFiles = paths.length > 1; | ||
|
|
||
| for (const path of paths) { | ||
| const counts = await wcFile(path); | ||
|
|
||
| total.lines += counts.lines; | ||
| total.words += counts.words; | ||
| total.bytes += counts.bytes; | ||
|
|
||
| console.log(formatOutput(counts, path, opts)); | ||
| } | ||
|
|
||
| if (multipleFiles) { | ||
| console.log(formatOutput(total, "total", opts)); | ||
| } | ||
| } | ||
|
|
||
| main(); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section has some repetition - two print formats, and two "print a number"s. The nested ifs are also a bit difficult to read. Can you think of any way to tidy this up?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for feedback
I created a new function to handle the repeated parts.