-
-
Notifications
You must be signed in to change notification settings - Fork 92
London | 26-SDC-Mar | Beko | Sprint 3 | Implement Shell Tools #500
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
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,44 @@ | ||
| import process from "node:process"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| const argv = process.argv.slice(2); | ||
|
|
||
| const dash = argv.filter(arg => arg.startsWith('-')); | ||
| const filePaths = argv.filter(arg => !arg.startsWith('-')); | ||
|
|
||
| const showLineNumbers = dash.includes('-n'); | ||
| const showNonBlank = dash.includes('-b'); | ||
|
|
||
| let lineCounter = 1; | ||
|
|
||
| for (const filePath of filePaths) { | ||
| let content; | ||
| try { | ||
| content = await fs.readFile(filePath, 'utf8'); | ||
| } catch { | ||
| console.error(`cat: ${filePath}: No file or directory exists`); | ||
| process.exit(1); | ||
| } | ||
|
|
||
| const lines = content.split('\n'); | ||
|
|
||
| if (lines[lines.length - 1] === '') lines.pop(); | ||
|
|
||
| for (const line of lines) { | ||
| const isBlank = line.trim() === ''; | ||
|
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. real cat treats lines with spaces as real lines and does not ignore them |
||
|
|
||
| if (showNonBlank) { | ||
| if (isBlank) { | ||
| console.log(''); | ||
| } else { | ||
| console.log(`${String(lineCounter).padStart(6)}\t${line}`); | ||
| lineCounter++; | ||
| } | ||
| } else if (showLineNumbers) { | ||
| console.log(`${String(lineCounter).padStart(6)}\t${line}`); | ||
| lineCounter++; | ||
| } else { | ||
| console.log(line); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| import process from "node:process"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| const argv = process.argv.slice(2); | ||
|
|
||
| const dash = argv.filter(arg => arg.startsWith('-')); | ||
| const paths = argv.filter(arg => !arg.startsWith('-')); | ||
|
|
||
| const showAll = dash.includes('-a'); | ||
|
|
||
| const targetDir = paths[0] ?? '.'; | ||
|
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 have multiple paths? |
||
|
|
||
| const entries = await fs.readdir(targetDir); | ||
|
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 happens if no dir is found? 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. entries is not sorted. readdir order is filesystem-dependent. Sort before output: entries.sort(). The . and .. entries should remain first. |
||
|
|
||
| const result = showAll ? ['.', '..', ...entries] : entries.filter(e => !e.startsWith('.')); | ||
|
|
||
| for (const entry of result) { | ||
| console.log(entry); | ||
|
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. Real ls default output is space-separated on one line; one-per-line requires the -1 flag. This always uses one-per-line regardless. The -1 flag needs to be implemented and the default output should join entries with spaces (plus a trailing newline). |
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,55 @@ | ||
| import process from "node:process"; | ||
| import { promises as fs } from "node:fs"; | ||
|
|
||
| const argv = process.argv.slice(2); | ||
|
|
||
| const dash = argv.filter(arg => arg.startsWith('-')); | ||
| const filePaths = argv.filter(arg => !arg.startsWith('-')); | ||
|
|
||
| const forLines = dash.includes('-l'); | ||
| const forWords = dash.includes('-w'); | ||
| const forBytes = dash.includes('-c'); | ||
|
|
||
| let totalLines = 0; | ||
| let totalWords = 0; | ||
| let totalBytes = 0; | ||
|
|
||
| for (const filePath of filePaths) { | ||
| let content; | ||
| try { | ||
| content = await fs.readFile(filePath, 'utf8'); | ||
| } catch { | ||
| console.error(`wc: ${filePath}: No file or directory exists`); | ||
| process.exit(1); | ||
|
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. Same situation: if one file is problematic, the whole execution stops. Real wc continues processing of other files. |
||
| } | ||
|
|
||
| const lines = content.split('\n').length - 1; | ||
| const words = content.trim() === '' ? 0 : content.trim().split(/\s+/).length; | ||
| const bytes = Buffer.byteLength(content, 'utf8'); | ||
|
|
||
| totalLines += lines; | ||
| totalWords += words; | ||
| totalBytes += bytes; | ||
|
|
||
| if (forLines) { | ||
|
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 happens if we have several flags simultaneously? |
||
| console.log(`${String(lines).padStart(8)} ${filePath}`); | ||
| } else if (forWords) { | ||
| console.log(`${String(words).padStart(8)} ${filePath}`); | ||
| } else if (forBytes) { | ||
| console.log(`${String(bytes).padStart(8)} ${filePath}`); | ||
| } else { | ||
| console.log(`${String(lines).padStart(8)} ${String(words).padStart(8)} ${String(bytes).padStart(8)} ${filePath}`); | ||
| } | ||
| } | ||
|
|
||
| if (filePaths.length > 1) { | ||
| if (forLines) { | ||
|
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 have several flags passed? |
||
| console.log(`${String(totalLines).padStart(8)} total`); | ||
| } else if (forWords) { | ||
| console.log(`${String(totalWords).padStart(8)} total`); | ||
| } else if (forBytes) { | ||
| console.log(`${String(totalBytes).padStart(8)} total`); | ||
| } else { | ||
| console.log(`${String(totalLines).padStart(8)} ${String(totalWords).padStart(8)} ${String(totalBytes).padStart(8)} total`); | ||
| } | ||
| } | ||
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 will stop processing of other files. Real cat continues processing of other files.