generated from CodeYourFuture/Module-Template
-
-
Notifications
You must be signed in to change notification settings - Fork 42
WestMidlands | SDC-NOV-2025 | SARA TAHIR | Sprint 3 | Implement Shell Tools #243
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
Open
SaraTahir28
wants to merge
11
commits into
CodeYourFuture:main
Choose a base branch
from
SaraTahir28:Feature/ImplementShell-Nodejs
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
de68e2e
Implementing cat with process.argv-node feature to access what user t…
SaraTahir28 fdbd244
Adding gitignore and package.json for installing dependencies
SaraTahir28 007ee54
Adding implementation to count number of lines
SaraTahir28 56e2740
Adding implementation for the b flag
SaraTahir28 1bcd513
implementation for ls -1 flag.
SaraTahir28 e44078e
Adding implementation for -a flag
SaraTahir28 99aae23
Refactoring code with helper functions and removing trailing extra li…
SaraTahir28 e8c2041
node implementation for wc
SaraTahir28 6152444
Fix -a flag handling to include current and parent dir while running …
SaraTahir28 9463024
Removed the duplicated code for line formatting
SaraTahir28 3de9968
Removing duplication of output code with a helper function.
SaraTahir28 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| # Node modules | ||
| node_modules/ | ||
|
|
||
| # Package lock file (optional) | ||
| package-lock.json |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,54 @@ | ||
| //On macOS (BSD cat), the -n option resets numbering for each file, so multiple files start again at 1, | ||
| //when you run cat -n sample-files/*.txt | ||
| //This Node.js script mimics GNU cat, where -n continues numbering across all files instead of restarting. | ||
| import { program } from "commander"; | ||
| import {promises as fs} from "node:fs" | ||
|
|
||
| //configuring the program here to run flags. | ||
|
|
||
| program | ||
| .name("cat") | ||
| .description("Concatenate and print files") | ||
| .option("-n, --number", "Number all output lines") | ||
| .option("-b, --number-nonblank", "Number non-blank output lines") | ||
| .argument("<files...>", "File paths to display") | ||
| .parse(process.argv);//Parse command line arguments (reads process.argv and interprets it) | ||
|
|
||
|
|
||
| //Constants | ||
| const paddingWidth = 6; // width for line number padding | ||
|
|
||
| // Helper function to format a line with numbering | ||
| function formatLine(line, lineNumber, numberAll, numberNonBlank) { | ||
| const numbered =`${lineNumber.toString().padStart(paddingWidth)} ${line}`; | ||
| if (numberAll) { | ||
| return numbered | ||
| } | ||
| if (numberNonBlank) { | ||
| return line.trim() === "" ? line : numbered; | ||
| } | ||
| return line; | ||
| } | ||
| const options = program.opts(); | ||
| const files = program.args; // Array of file paths passed as arguments | ||
|
|
||
| let lineNumber = 1; // shared across all files | ||
|
|
||
| for (const file of files) { | ||
| const content = await fs.readFile(file, "utf-8"); | ||
| let lines = content.split("\n"); | ||
| // Remove trailing empty line if file ends with newline | ||
| if (lines.length > 0 && lines[lines.length - 1] === "") { | ||
| lines.pop(); | ||
| } | ||
|
|
||
| for (const line of lines) { | ||
| const formatted = formatLine(line, lineNumber, options.number, options.numberNonblank); | ||
| console.log(formatted); | ||
|
|
||
| // Increment line number if numbering applies | ||
| if (options.number || (options.numberNonblank && line.trim() !== "")) { | ||
| lineNumber++; | ||
| } | ||
| } | ||
| } | ||
|
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. Very nice, cleanly written implementation |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,39 @@ | ||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| //configuring | ||
| program | ||
| .name("ls") | ||
| .description("list directory contents") | ||
| .option("-1, --one", "Outputs are printed one entry per line") | ||
| .option("-a, --all","Show all files including hidden files that start with a .") | ||
| .argument("[directory]", "Directory to list", "."); // "." means current directory | ||
|
|
||
| //interpret the program | ||
| program.parse(); | ||
| const options = program.opts(); | ||
| const directory = program.args[0] || "."; //get dir arg- 1st arg in program.args array || if no arg default to current dir | ||
|
|
||
|
|
||
| let files = await fs.readdir(directory); //read the dir to get array of filenames | ||
|
|
||
| //Handle -a (include hidden files) | ||
| // Node's fs.readdir() does not include the special directory entries "." (current dir) | ||
| // and ".." (parent dir). The real `ls -a` command shows them, so we add them manually here | ||
| // to match the behavior of `ls -a`. | ||
| if (options.all) { | ||
|
|
||
| files.unshift(".."); | ||
| files.unshift("."); | ||
| } else { | ||
| files = files.filter(name => !name.startsWith(".")); | ||
| } | ||
|
|
||
| if (options.one) { // Print each file on its own line | ||
| for (const file of files) { | ||
| console.log(file); | ||
| } | ||
| } | ||
| else { | ||
| console.log(files.join(" "));// Default: join with spaces (like ls without -1) | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,6 @@ | ||
| { | ||
| "type": "module", | ||
| "dependencies": { | ||
| "commander": "^14.0.2" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,61 @@ | ||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| //configuring | ||
| program | ||
| .name("wc") | ||
| .description("Print newline, word, and byte counts for each file") | ||
| .option("-l, --lines", "Print the newline counts") | ||
| .option("-w, --words", "Print the word counts") | ||
| .option("-c, --bytes", "Print the byte counts") | ||
| .argument("<files...>", "File paths to process") | ||
| //Interpret the program | ||
| program.parse() | ||
| const options = program.opts() | ||
| const files = program.args //Interpreting parsed data | ||
|
|
||
|
|
||
| //helper function to calculate all counts | ||
| async function getCounts(file){ | ||
| const content = await fs.readFile(file, "utf-8"); | ||
| const lineCount = content.split("\n").length -1;//split("\n") returns one more element than the actual number so length-1, | ||
| const wordCount = content.trim().split(/\s+/).length; | ||
| const byteCount = Buffer.byteLength(content, "utf-8"); //Calculate how many bytes the string uses in UTF-8 (important because some characters use more than 1 byte) | ||
| return { lineCount, wordCount, byteCount }; | ||
| } | ||
| //helper to remove duplicated output logic | ||
| function formatOutput(lines, words, bytes, filename, options) { | ||
| let formattedOutput = ""; | ||
| if (options.lines) formattedOutput += `${lines} `; | ||
| if (options.words) formattedOutput+= `${words} `; | ||
| if (options.bytes) formattedOutput += `${bytes} `; | ||
| if (!options.lines && !options.words && !options.bytes) { // default: print all three | ||
| formattedOutput += `${lines} ${words} ${bytes} `; | ||
| } | ||
| return formattedOutput + filename; | ||
| } | ||
| //Initiating totals | ||
| let totalLines = 0; | ||
| let totalWords = 0; | ||
| let totalBytes = 0; | ||
|
|
||
| for (const file of files) { | ||
| const { lineCount, wordCount, byteCount } = await getCounts(file); | ||
|
|
||
| totalLines += lineCount; | ||
| totalWords += wordCount; | ||
| totalBytes += byteCount; | ||
|
|
||
| const formatted = formatOutput(lineCount, wordCount, byteCount, file, options); | ||
| console.log(formatted); | ||
| } | ||
| //Print totals if multiple files | ||
| if (files.length > 1) { | ||
| const formattedTotals = formatOutput(totalLines, totalWords, totalBytes, "total", options); | ||
| console.log(formattedTotals); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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 idea to pull this function out, but you could have taken advantage of this to reduce the duplication of the string formatting code, which appears twice.
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.
Thankyou for pointing that out, I have removed teh duplication.