-
-
Notifications
You must be signed in to change notification settings - Fork 92
NW | 2026-MAR-SDC | Ahmad Hmedan | Sprint 3 | Implement shell tool #452
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 all commits
dd574ac
0edb723
1ffd705
7036a76
a2934e7
58f7d44
6c2dcfa
248f9de
383f3a6
b8b055e
3758f99
57768d0
029b379
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,60 @@ | ||
| import { promises as fs } from "node:fs"; | ||
| import { program } from "commander"; | ||
|
|
||
| program | ||
| .name("cat") | ||
| .description("my own cat program") | ||
| .option("-n", "number all lines") | ||
| .option("-b" , "number non-empty lines") | ||
| .argument("<paths...>", "The file path to process"); | ||
| program.parse(); | ||
|
|
||
| const paths = program.args; | ||
| const options = program.opts(); | ||
|
|
||
| if (paths.length === 0) { | ||
| console.error("Expected at least one argument (a path)"); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| let lineNumber = 1; | ||
|
|
||
| for (const path of paths) { | ||
| try { | ||
| const content = await fs.readFile(path, "utf-8"); | ||
| if(options.b) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What if we decrease the complexity of the logic (amount of nested blocks) by extracting all the output logic into a separate function? |
||
| { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what is javascript convention for braces placement? |
||
| const lines = content.split("\n"); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. could you align the column on this line? |
||
|
|
||
| if (lines[lines.length - 1] === "") { | ||
| lines.pop(); | ||
| } | ||
| for(const line of lines) | ||
| { | ||
| if(line.trim()!=="") | ||
| { | ||
| process.stdout.write(` ${lineNumber} ${line}\n`); | ||
| lineNumber++; | ||
| } | ||
| else {process.stdout.write("\n");} | ||
| } | ||
|
|
||
| } | ||
| else if (options.n) { | ||
| const lines = content.split("\n"); | ||
|
|
||
| if (lines[lines.length - 1] === "") { | ||
| lines.pop(); | ||
| } | ||
|
|
||
| for (const line of lines) { | ||
| process.stdout.write(` ${lineNumber} ${line}\n`); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. By default, cat -n right-justifies the line number in a 6-character-wide field, followed by a tab. |
||
| lineNumber++; | ||
| } | ||
| } else { | ||
| process.stdout.write(content); | ||
| } | ||
| } catch (error) { | ||
| console.error(error.message); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What will return real cat if at least one file had errors during processing? |
||
| } | ||
| } | ||
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,15 @@ | ||
| { | ||
| "name": "cat", | ||
| "version": "1.0.0", | ||
| "description": "You should already be familiar with the `cat` command line tool.", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "dependencies": { | ||
| "commander": "^14.0.3" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { promises as fs } from "node:fs"; | ||
| import { program } from "commander"; | ||
|
|
||
| program | ||
| .name("ls ") | ||
| .description("ls implementation") | ||
| .argument("[path]", "The path to process") | ||
| .option("-1, --one-per-line", "one file per line") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we have logic processing this parameter? |
||
| .option("-a", "show hidden files"); | ||
| program.parse(); | ||
|
|
||
| const path = program.args[0] || "."; | ||
| const options = program.opts(); | ||
| try { | ||
| const files = await fs.readdir(path); | ||
|
|
||
| for(const file of files) | ||
| { | ||
| if(!options.a && file.startsWith("."))continue; | ||
|
|
||
| console.log(file); | ||
| } | ||
| } catch (error) { | ||
| console.error(error.message); | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| import { program } from "commander"; | ||
|
|
||
| import { promises as fs} from "node:fs"; | ||
|
|
||
| program | ||
| .name("wc") | ||
| .description("wc implementation") | ||
| .argument("<paths...>", "the file path to process") | ||
| .option("-l", "count lines") | ||
| .option("-w", "count words") | ||
| .option("-c", "count characters"); | ||
|
|
||
| program.parse(); | ||
|
|
||
|
|
||
| const paths = program.args; | ||
|
|
||
| if (paths.length === 0) { | ||
| console.error("Expected at least one argument (a path)"); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const options = program.opts(); | ||
|
|
||
| const total = { | ||
| linesCounter: 0, | ||
| wordsCounter: 0, | ||
| characterCounter: 0, | ||
| }; | ||
|
|
||
|
|
||
| try { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. the existing wc would continue execution if there was single error handling a single file, could we do the same here? (Just in case, cat.mjs does it) |
||
| for (const path of paths) { | ||
| const content = await fs.readFile(path, "utf-8"); | ||
|
|
||
| const linesCounter = content.split("\n").length - 1; | ||
| const wordsCounter = content.trim().split(/\s+/).length; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what will happen with wordsCounter if the file content is empty? |
||
| const characterCounter = content.length; | ||
|
|
||
| total.linesCounter += linesCounter; | ||
| total.wordsCounter += wordsCounter; | ||
| total.characterCounter += characterCounter; | ||
|
|
||
| let results = []; | ||
| if (options.l) results.push(linesCounter); | ||
| if (options.w) results.push(wordsCounter); | ||
| if (options.c) results.push(characterCounter); | ||
|
|
||
| if (!options.l && !options.w && !options.c) | ||
| console.log( | ||
| ` ${linesCounter} ${wordsCounter} ${characterCounter} ${path}`, | ||
| ); | ||
| else { | ||
| console.log(results.join(" ") + " " + path); | ||
| } | ||
| } | ||
| if (paths.length > 1) { | ||
| if (!options.l && !options.w && !options.c) { | ||
| console.log( | ||
| ` ${total.linesCounter} ${total.wordsCounter} ${total.characterCounter} total`, | ||
| ); | ||
| } else { | ||
| const totalWithFlags = []; | ||
| if (options.l) totalWithFlags.push(total.linesCounter); | ||
| if (options.w) totalWithFlags.push(total.wordsCounter); | ||
| if (options.c) totalWithFlags.push(total.characterCounter); | ||
| console.log(totalWithFlags.join(" ") + " total"); | ||
| } | ||
| } | ||
| } catch (error) { | ||
| console.error(error.message); | ||
| } | ||
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.
good use of try catch