Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
Binary file added implement-shell-tools/.DS_Store
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 can you remove these .DS_Store files from your branch? Thanks!

Binary file not shown.
50 changes: 50 additions & 0 deletions implement-shell-tools/cat/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { readFileSync } from "node:fs";

function cleanInput(listOfFiles) {
let cleanLinesArr = [];

for (const file of listOfFiles) {
const grabbedText = readFileSync(file, "utf-8");
const splitLines = grabbedText.split("\n");
cleanLinesArr.push(...splitLines);
}
return cleanLinesArr;
}

const args = process.argv.slice(2);
let flag;
let restIsFiles;

if (args[0] && args[0][0] === "-") {
flag = args[0];
restIsFiles = args.slice(1);
} else {
flag = null;
restIsFiles = args;
}

function takeSpecifiedAction(cleanLinesArr, flag) {
let countingOnlyFullLines = 1;

for (const file of cleanLinesArr) {
// Task: We recommend you start off supporting no flags, then add support for `-n`, then add support for `-b`.
if (!flag) {
console.log(file);
} else if (flag === "-n") {
console.log(`${countingOnlyFullLines} ${file}`);
countingOnlyFullLines += 1;
} else if (flag === "-b") {
if (file === "") {
console.log("");
} else {
console.log(`${countingOnlyFullLines} ${file}`);
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.

These ifs are quite repetitive, which has a couple of issues:

  1. When reading the code, it's hard to see which parts are the same across the branches, and what parts are different.
  2. In the future if we add new concerns (e.g. a "colour every other line" flag), we'll need to implement that across each of the branches.

We often solve this by separating "the differences" from "what's the same", e.g.

// Make a variable up-front:
let prefix = "";
// Conditionally change things
if (something) {
  prefix = "hello";
} else if (somethingElse) {
  prefix = "goodbye";
}
console.log(`${prefix}${line}`);

So that the ifs at the start make clear how things are different, and what comes after shows what's the same/different

countingOnlyFullLines += 1;
}
} else {
console.log("incorrect flag");
}
}
}

const lines = cleanInput(restIsFiles);
takeSpecifiedAction(lines, flag);
41 changes: 41 additions & 0 deletions implement-shell-tools/ls/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import process from "node:process";
import { promises as fs } from "node:fs";

// `ls -1`
async function showAllFilesInDir(directory) {
const listOfFiles = await fs.readdir(directory);

for (const eachFile of listOfFiles) {
if (eachFile[0] !== ".") console.log(eachFile);
}
}

// `ls -1 sample-files`
async function showVisibleInSampleFiles() {
const listOfFiles = await fs.readdir("sample-files");
Comment on lines +14 to +15
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.

We generally don't want to hard-code that our program only works with specific directories - can you think how to make this more general? And how to make it share code with the other two functions?


for (const eachFile of listOfFiles) {
if (eachFile[0] !== ".") {
console.log(eachFile);
}
}
}

// `ls -1 -a sample-files`
async function showAllInSampleFiles() {
const listOfFiles = await fs.readdir("sample-files");

for (const eachFile of listOfFiles) {
console.log(eachFile);
}
}

const argv = process.argv.slice(2);

if (argv.includes("-a")) {
await showAllInSampleFiles();
} else if (argv.includes("sample-files")) {
await showVisibleInSampleFiles();
} else {
await showAllFilesInDir(".");
}
74 changes: 74 additions & 0 deletions implement-shell-tools/wc/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import process from "node:process";
import { promises as fs } from "node:fs";

//from coursework
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 remove the assorted commented out code :)

// const content = await fs.readFile(path, "utf-8");
// const countOfWordsContainingEs = content
// .split(" ")
// .filter((word) => word.includes("e"))
// .length;
// console.log(countOfWordsContainingEs);

function calculateCounts(inputFiles) {
return {
lines: inputFiles.split("\n").length - 1,
words: inputFiles.split(/\s+/).filter((w) => w !== "").length,
bytes: inputFiles.length,
};
}

// * `wc -l sample-files/3.txt`
// * `wc -l sample-files/*`
async function countLines(listOfFiles) {
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.

These functions are quite repetitive with each other.

for (const file of listOfFiles) {
const content = await fs.readFile(file, "utf-8");

// const linesNumbered = content.split('\n').length-1
const counts = calculateCounts(content);
console.log(`${counts.lines} ${file}`);
}
}

// * `wc -w sample-files/3.txt`
async function countWords(listOfFiles) {
for (const file of listOfFiles) {
const content = await fs.readFile(file, "utf-8");

// const wordsCounted = content.split(" ").filter(word => word !== "").length;
// console.log(`${wordsCounted} ${file}`);
const counts = calculateCounts(content);
console.log(`${counts.words} ${file}`);
}
}

// * `wc -c sample-files/3.txt`
async function countBytes(listOfFiles) {
for (const file of listOfFiles) {
const content = await fs.readFile(file, "utf-8");
// const bytesCounted = content.length;
const counts = calculateCounts(content);
console.log(`${counts.bytes} ${file}`);
}
}

// * `wc sample-files/*`
async function countAll(listOfFiles) {
for (const file of listOfFiles) {
const content = await fs.readFile(file, "utf-8");
const counts = calculateCounts(content);
console.log(`${counts.lines} ${counts.words} ${counts.bytes} ${file}`);
}
}

const argv = process.argv.slice(2);
const files = argv.filter((arg) => !arg.startsWith("-"));

if (argv.includes("-l")) {
await countLines(files);
} else if (argv.includes("-w")) {
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 real wc also supports passing multiple of the flags at once (e.g. wc -w -l /some/file), and does something a bit different if you pass multiple files (wc -w -c /some/file /some/other/file) - can you see if you can match those behaviours?

await countWords(files);
} else if (argv.includes("-c")) {
await countBytes(files);
} else {
await countAll(files);
}
Loading