Skip to content

London | 26-SDC-MAR | Jamal Laqdiem | Sprint 3 | Implement Shell Tools#437

Open
jamallaqdiem wants to merge 5 commits intoCodeYourFuture:mainfrom
jamallaqdiem:implement-shell-tools
Open

London | 26-SDC-MAR | Jamal Laqdiem | Sprint 3 | Implement Shell Tools#437
jamallaqdiem wants to merge 5 commits intoCodeYourFuture:mainfrom
jamallaqdiem:implement-shell-tools

Conversation

@jamallaqdiem
Copy link
Copy Markdown

Learners, PR Template

Self checklist

  • [ x] I have titled my PR with Region | Cohort | FirstName LastName | Sprint | Assignment Title
  • [ x] My changes meet the requirements of the task
  • [ x] I have tested my changes
  • [ x] My changes follow the style guide

Changelist

shell tools exercises.

@jamallaqdiem jamallaqdiem added Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. Module-Tools The name of the module. 📅 Sprint 3 Assigned during Sprint 3 of this module labels Mar 26, 2026
Comment thread implement-shell-tools/cat/cat.js Outdated
}
});
} catch (error) {
console.log(`Could not read: ${path}`);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If there's an error where will this message get printed? stdout or stderr? And what exit code would the process exit with?

Do these match our expectations from shell tools?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing, I made the changes from console.log that wil send txt to stdout To console.error that willsend to stderr and display the error in the screen.
Added pocess.exit(1) to make sure that in case of failure the code should exit with a non zero code.

Comment thread implement-shell-tools/cat/cat.js Outdated
Comment on lines +24 to +34
console.log(`${counterLines++} ${line}`);
} else if (showNonBlankNumbers) {
// increment and show numbers only if the line is not empty.
if (line.trim() !== "") {
console.log(`${counterLines++} ${line}`);
} else {
// print empty lines
console.log(line);
}
} else {
console.log(line);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The three branches here look quite similar and repetitive. In general, if you have multiple similar branches, it's more clear to extract the differences into variables, and then run the same code, i.e. so you'd only have one call to console.log which looks more like console.log(`${prefix}${line}\n`) where prefix may be set differently based on options (including potentially an empty string).

This way it's easier for someone reading the code to see what's the same / different in each case, and also avoids the hazard that someone updates one of the branches but forgets to update the other ones.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing, I followed your correct instructions , as it's much clearer and readable using a variable.

const showNonBlankNumbers = argv.includes("-b");

//filter the - from the array argv as it's a flag.
const filePaths = argv.filter((arg) => !arg.startsWith("-"));
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen if someone passed a -q flag here? What should happen?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing, you are right to point that out, my logic will let the user confused thinking that the -q flag exists and worked, I implemented in place a flag check and ensured print an error and exit with not 0 code.

const showHiddenFiles = argv.includes("-a");

// if no folder provide we use the current one
const target = filePaths[0] || ".";
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would happen if someone specified multiple paths, e.g. ls /some/file /some/other/file? What does your implementation do?

The README.md only requires that your programme works with simple paths, but I would recommend implementing support for multiple. But if you don't implement that, you generally want to give an error to the user if they supply input you don't expect, rather than just ignoring it.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing, I should at least display an stderr and exit .

Comment thread implement-shell-tools/wc/wc.js Outdated
filePaths.forEach((filePath) => {
const content = fs.readFileSync(filePath, "utf-8");

const lines = content.split("\n").length - 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you have to - 1 here?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing, I used -1 because my vscode automatically add a new line when save, so in this case split method will add an empty element, however in other environments this logic my fail if no trialling new line added .

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We may add a conditional check using .pop method in case of empty string at the end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do the conditional pop check :)

Comment thread implement-shell-tools/wc/wc.js Outdated

let output = "";

if (showLines || noFlags) output += `${lines} `;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you think of a way to achieve this same result, but without needing a noFlags variable at all?

If our program was bigger and more complicated, in most of the program we don't want to have to think about what the exact flags interface was. Ideally we can just look at showLines to decide whether we should show lines, without needing to worry which exactly flags led to us needing to show lines.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing, I implemented a clear way to switch all flags to true if no flag was picked.
Fixed a bug.

@illicitonion illicitonion added Reviewed Volunteer to add when completing a review with trainee action still to take. and removed Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. labels Apr 10, 2026
@jamallaqdiem jamallaqdiem added the Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. label Apr 11, 2026
Comment thread implement-shell-tools/cat/cat.js Outdated
// THis will give an array without the path to node and to the file.
const argv = process.argv.slice(2);

//Get line numbers.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this comment provide value beyond the variable names?

If yes, could you change the variable names to make this comment no longer necessary?

Comment thread implement-shell-tools/cat/cat.js Outdated
const supportedFlags = ["-n", "-b"];
for (const flag of flagsUsed) {
if (!supportedFlags.includes(flag)) {
console.error(`Invalid option try 'node cat.js --help' for more info.`);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does node cat.js --help do? As far as I can tell, it will probably print this error?

Comment thread implement-shell-tools/cat/cat.js Outdated
Comment on lines +44 to +45
} catch (error) {
console.error(`Could not read: ${path}`);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right now you're always printing the same error message if something went wrong.

What are the advantages/disadvantages to including the specific error message in the output to the user?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The advantages is that will show the users the error and allow him to adjusted themselves.
The disadvantages is that it may leak sensitive data like a name in the path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is generally correct, though specific on names in the path, the user presumably has access to the name in the path because if they didn't they wouldn't have been able to pass it as an argument.

Comment thread implement-shell-tools/ls/ls.js Outdated
// read the file.
const files = fs.readdirSync(target);

// save the result into the variable.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Almost all of your comments provide no value over just reading the code. Comments should explain why we're doing something (if it's not obvious), or explain something particularly confusing/tricky. If you can read the code, the comments here aren't useful - please consider all of them and remove any you think aren't useful.

}
// fix bug .length ===0 will be true if nothing provided, instead !filePath will return empty array which result true.
if (filePaths.length === 0) {
console.error("PLease provide a file path");
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You frequently have typos where the second letter after a capital letter is also capitalised. Please look out for these and fix them.

Comment thread implement-shell-tools/wc/wc.js Outdated
filePaths.forEach((filePath) => {
const content = fs.readFileSync(filePath, "utf-8");

const lines = content.split("\n").length - 1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do the conditional pop check :)

Comment thread implement-shell-tools/wc/wc.js Outdated
if (showCharacters) output += `${characters} `;

console.log(`${output} ${filePath}`);
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your output doesn't match real wc's output if multiple files were passed. Please make sure to run the examples given in the READMEs and that your behaviours match.

@illicitonion illicitonion removed the Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. label Apr 22, 2026
@jamallaqdiem
Copy link
Copy Markdown
Author

Thanks for the review, I addressed all matters.

@jamallaqdiem jamallaqdiem added the Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. label Apr 25, 2026
Copy link
Copy Markdown
Member

@illicitonion illicitonion left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks much better, well done!

Comment on lines +31 to +37
if (showNonBlankNumbers) {
if (line.trim() !== "") {
prefix = `${counterLines++} `;
}
} else if (showNumbers) {
prefix = `${counterLines++} `;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would think about collapsing this into one if:

if (showNumbers || (howNonBlankNumbers && line.trim() !== "")) {

because they have the same intent, but wouldn't push strongly for this if you prefer it as-is :)


const files = fs.readdirSync(target);

let filteredFIles = files;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
let filteredFIles = files;
let filteredFiles = files;


if (filePaths.length > 1) {
let totalOutput = "";
if (showLines) totalOutput += `${totalLines.toString().padStart(8)}`;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit repetitive with the single-file formatting case :)

Comment thread implement-shell-tools/cat/cat.js Outdated
Comment on lines +44 to +45
} catch (error) {
console.error(`Could not read: ${path}`);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is generally correct, though specific on names in the path, the user presumably has access to the name in the path because if they didn't they wouldn't have been able to pass it as an argument.

@illicitonion illicitonion added Complete Volunteer to add when work is complete and all review comments have been addressed. and removed Needs Review Trainee to add when requesting review. PRs without this label will not be reviewed. Reviewed Volunteer to add when completing a review with trainee action still to take. labels Apr 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Complete Volunteer to add when work is complete and all review comments have been addressed. Module-Tools The name of the module. 📅 Sprint 3 Assigned during Sprint 3 of this module

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants