generated from CodeYourFuture/Module-Template
-
-
Notifications
You must be signed in to change notification settings - Fork 47
London | 25-SDC-July | Eyuel Abraham | Sprint 3 | Implement shell tools #125
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
eyuell21
wants to merge
12
commits into
CodeYourFuture:main
Choose a base branch
from
eyuell21:implement-shell-tools
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.
+363
−0
Open
Changes from all commits
Commits
Show all changes
12 commits
Select commit
Hold shift + click to select a range
0082e59
Completed ls-grep exercises
eyuell21 fedfb04
Completed sort-uniq-head-tail exercises.
eyuell21 18f4d32
Completed tr exercises.
eyuell21 a0f8ccb
Added a .gitignore file.
eyuell21 af21d2c
cat command implementation.
eyuell21 4179068
ls command implementation.
eyuell21 523342a
wc command implementation.
eyuell21 1b1928e
.venv added to gitignore.
eyuell21 f2279d9
Fix according to PR reviews
eyuell21 7ca6ac1
Added a module type declaration.
eyuell21 1b40c9d
Implemented an output formatting function.
eyuell21 784057b
Calculate total lines for -n option in cat command implementation
eyuell21 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 |
|---|---|---|
| @@ -1 +1,2 @@ | ||
| node_modules | ||
| .venv |
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,7 @@ | ||
| # Ignore node_modules everywhere | ||
| **/node_modules/ | ||
|
|
||
| #ignore logs, environment files. | ||
| *.log | ||
| .env | ||
| dist/ |
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,75 @@ | ||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
| import process from "node:process"; | ||
|
|
||
| program | ||
| .name("my-cat") | ||
| .description("Reads and prints one or more files, optionally numbering lines continuously") | ||
| .argument("<paths...>", "One or more file paths") | ||
| .option("-n, --number", "Number all output lines", false) | ||
| .option("-b, --number-nonblank", "Number non-empty output lines", false); | ||
|
|
||
| program.parse(); | ||
|
|
||
| const filePaths = program.args; | ||
| const options = program.opts(); | ||
|
|
||
| const numberNonBlank = options.numberNonblank; | ||
| const numberAll = options.number && !numberNonBlank; | ||
|
|
||
| (async () => { | ||
| let lineNumber = 1; | ||
|
|
||
| // calculate total lines if using -n | ||
| let totalLines = 0; | ||
| if (numberAll) { | ||
| for (const path of filePaths) { | ||
| try { | ||
| const content = await fs.readFile(path, "utf-8"); | ||
| const lines = content.split("\n"); | ||
|
|
||
| totalLines += content.endsWith("\n") ? lines.length - 1 : lines.length; | ||
| } catch (err) { | ||
| console.error(`Error reading file "${path}": ${err.message}`); | ||
| process.exit(1); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| for (const path of filePaths) { | ||
| try { | ||
| const content = await fs.readFile(path, "utf-8"); | ||
| const lines = content.split("\n"); | ||
|
|
||
| if (numberNonBlank) { | ||
| const maxDigits = String(lines.filter(line => line.trim() !== '').length).length; | ||
|
|
||
| for (const line of lines) { | ||
| if (line.trim() === '') { | ||
| process.stdout.write("\n"); | ||
| } else { | ||
| const numStr = String(lineNumber++).padStart(maxDigits, " "); | ||
| process.stdout.write(`${numStr}\t${line}\n`); | ||
| } | ||
| } | ||
| } else if (numberAll) { | ||
| const maxDigits = totalLines > 0 ? String(totalLines).length : 1; | ||
|
|
||
|
|
||
| for (const line of lines) { | ||
| const numStr = String(lineNumber++).padStart(maxDigits, " "); | ||
| process.stdout.write(`${numStr}\t${line}\n`); | ||
| } | ||
| } else { | ||
| // no numbering, just print file content as is | ||
| process.stdout.write(content); | ||
| if (!content.endsWith("\n")) { | ||
| process.stdout.write("\n"); // ensure newline after file if missing | ||
| } | ||
| } | ||
| } catch (err) { | ||
| console.error(`Error reading file "${path}": ${err.message}`); | ||
| process.exit(1); | ||
| } | ||
| } | ||
| })(); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,16 @@ | ||
| { | ||
| "name": "cat", | ||
| "version": "1.0.0", | ||
| "description": "You should already be familiar with the `cat` command line tool.", | ||
| "main": "cat.js", | ||
| "type": "module", | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC", | ||
| "dependencies": { | ||
| "commander": "^14.0.0" | ||
| } | ||
| } | ||
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,69 @@ | ||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
| import path from "node:path"; | ||
|
|
||
| program | ||
| .name("my-ls") | ||
| .description("List files in a directory (simplified ls implementation)") | ||
| .argument("[paths...]", "One or more file or directory paths") | ||
| .option("-l, --longList", "Long listing format", false) | ||
| .option("-a, --all", "Include hidden files", false); | ||
|
|
||
| program.parse(); | ||
|
|
||
| // CHANGED: apply default value for paths here if none are provided | ||
| let filePaths = program.args.length > 0 ? program.args : ['.']; | ||
| const options = program.opts(); | ||
|
|
||
| const showLong = options.longList; | ||
| const showAll = options.all; | ||
|
|
||
| // Helper function to convert mode to rwxrwxrwx string | ||
| function formatPermissions(mode, isDir) { | ||
| const typeChar = isDir ? 'd' : '-'; | ||
| const perms = [0, 1, 2].map(i => { | ||
| const shift = 6 - i * 3; | ||
| const r = (mode >> shift) & 4 ? 'r' : '-'; | ||
| const w = (mode >> shift) & 2 ? 'w' : '-'; | ||
| const x = (mode >> shift) & 1 ? 'x' : '-'; | ||
| return r + w + x; | ||
| }).join(''); | ||
| return typeChar + perms; | ||
| } | ||
|
|
||
| (async () => { | ||
| for (const inputPath of filePaths) { | ||
| try { | ||
| const stat = await fs.stat(inputPath); | ||
|
|
||
| if (stat.isFile()) { | ||
| if (showLong) { | ||
| const perms = formatPermissions(stat.mode, false); | ||
| console.log(`${perms} ${stat.size.toString().padStart(6)} ${inputPath}`); | ||
| } else { | ||
| console.log(inputPath); | ||
| } | ||
| } else if (stat.isDirectory()) { | ||
| const entries = await fs.readdir(inputPath, { withFileTypes: true }); | ||
|
|
||
| const filtered = showAll | ||
| ? entries | ||
| : entries.filter((entry) => !entry.name.startsWith(".")); | ||
|
|
||
| for (const entry of filtered) { | ||
| const fullPath = path.join(inputPath, entry.name); | ||
| const entryStat = await fs.stat(fullPath); | ||
| if (showLong) { | ||
| const perms = formatPermissions(entryStat.mode, entryStat.isDirectory()); | ||
| console.log(`${perms} ${entryStat.size.toString().padStart(6)} ${entry.name}`); | ||
| } else { | ||
| console.log(entry.name); | ||
| } | ||
| } | ||
| } | ||
| } catch (err) { | ||
| console.error(`Error reading "${inputPath}": ${err.message}`); | ||
| process.exit(1); | ||
| } | ||
| } | ||
| })(); |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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,17 @@ | ||
| { | ||
| "dependencies": { | ||
| "commander": "^14.0.0" | ||
| }, | ||
| "name": "ls", | ||
| "version": "1.0.0", | ||
| "description": "You should already be familiar with the `ls` command line tool.", | ||
| "main": "ls.js", | ||
| "type": "module", | ||
| "devDependencies": {}, | ||
| "scripts": { | ||
| "test": "echo \"Error: no test specified\" && exit 1" | ||
| }, | ||
| "keywords": [], | ||
| "author": "", | ||
| "license": "ISC" | ||
| } |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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.0" | ||
| } | ||
| } |
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,74 @@ | ||
| import { program } from "commander"; | ||
| import { promises as fs } from "node:fs"; | ||
| import { stat } from "node:fs/promises"; | ||
|
|
||
| program | ||
| .name("my-wc") | ||
| .description("Simplified implementation of wc") | ||
| .argument("[paths...]", "One or more file or directory paths") | ||
| .option("-l, --line", "Count lines") | ||
| .option("-w, --word", "Count words") | ||
| .option("-c, --character", "Count characters"); | ||
|
|
||
| program.parse(); | ||
|
|
||
| const filePaths = program.args.length > 0 ? program.args : ['.']; | ||
| const options = program.opts(); | ||
|
|
||
| const countContent = (content) => { | ||
| const lines = content.split('\n').length; | ||
| const words = content.trim().split(/\s+/).filter(Boolean).length; | ||
| const characters = content.length; | ||
| return { lines, words, characters }; | ||
| }; | ||
|
|
||
| const total = { | ||
| lines: 0, | ||
| words: 0, | ||
| characters: 0 | ||
| }; | ||
|
|
||
| //Output formatting function | ||
| function formatOutput(counts, label, options) { | ||
| const { lines, words, characters } = counts; | ||
| const showAll = !options.line && !options.word && !options.character; | ||
|
|
||
| const parts = []; | ||
|
|
||
| if (options.line || showAll) parts.push(lines.toString().padStart(8)); | ||
| if (options.word || showAll) parts.push(words.toString().padStart(8)); | ||
| if (options.character || showAll) parts.push(characters.toString().padStart(8)); | ||
|
|
||
| parts.push(label); | ||
| return parts.join(" "); | ||
| } | ||
|
|
||
| (async () => { | ||
| let fileCount = 0; | ||
|
|
||
| for (const inputPath of filePaths) { | ||
| try { | ||
| const stats = await stat(inputPath); | ||
| if (stats.isDirectory()) { | ||
| console.log(`${inputPath} is a directory. Skipping.`); | ||
| continue; | ||
| } | ||
|
|
||
| const content = await fs.readFile(inputPath, "utf-8"); | ||
| const counts = countContent(content); | ||
|
|
||
| total.lines += counts.lines; | ||
| total.words += counts.words; | ||
| total.characters += counts.characters; | ||
| fileCount++; | ||
|
|
||
| console.log(formatOutput(counts, inputPath, options)); | ||
| } catch (err) { | ||
| console.error(`Error reading "${inputPath}": ${err.message}`); | ||
| } | ||
| } | ||
|
|
||
| if (fileCount > 1) { | ||
| console.log(formatOutput(total, "total", options)); | ||
| } | ||
| })(); |
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
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
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
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
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
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
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
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
Oops, something went wrong.
Oops, something went wrong.
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.
Uh oh!
There was an error while loading. Please reload this page.