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
35 changes: 19 additions & 16 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"devDependencies": {
"@faker-js/faker": "^8.4.1",
"@mate-academy/eslint-config": "latest",
"@mate-academy/scripts": "^1.8.6",
"@mate-academy/scripts": "^2.1.3",
"eslint": "^8.57.0",
"eslint-plugin-jest": "^28.6.0",
"eslint-plugin-node": "^11.1.0",
Expand Down
79 changes: 78 additions & 1 deletion src/app.js
Original file line number Diff line number Diff line change
@@ -1 +1,78 @@
// write code here
/* eslint-disable no-console */
const path = require('path');
const fs = require('fs');

const moveFile = () => {
const [file, destination] = process.argv.slice(2);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You destructure the CLI args here into file and destination, but you never keep the original destination string to check for a trailing slash. The spec requires treating a destination that ends with / as a directory. Store the raw argument (e.g. const [file, rawDestination] = ...) before calling path.resolve so you can detect rawDestination.endsWith('/'). See the description for this rule.


if (!file || !destination) {
console.error('Usage: node app.js <file> <destination>');

return;
}

const sourcePath = path.resolve(file);
const destinationPath = path.resolve(destination);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You call path.resolve(destination) which removes the trailing slash; because of that the code cannot tell whether the user intended a directory (e.g. dir/) and may create a file named dir instead of throwing when the directory is missing. Detect the trailing slash on the original arg before resolving and enforce directory-exists behavior when the trailing slash is present.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You call path.resolve(destination) here before inspecting the raw CLI destination. The task requires preserving and checking the raw destination (e.g. rawDestination.endsWith(...)) before calling path.resolve so trailing-slash semantics are not lost. Capture the raw argument first and check it prior to resolving.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

You call path.resolve(destination) here before following the requirement to preserve and inspect the raw CLI argument for a trailing separator. Capture the raw argument first (e.g. const rawDestination = process.argv[3];) and check its trailing separator before resolving into destinationPath so resolving can't remove the trailing-separator information.


if (sourcePath === destinationPath) {
return;
}

let data;

try {
data = fs.readFileSync(sourcePath);
} catch (err) {
console.error(err.message);

return;
}

try {
if (destination.endsWith('/')) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

This check only tests for a POSIX '/' trailing separator. Per the spec you must accept both '/' and the platform separator. Use something like rawDestination.endsWith('/') || rawDestination.endsWith(path.sep) and ensure you inspect the raw argument (not the resolved one) for that condition.

if (!fs.existsSync(destination)) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When treating the destination as a directory you call fs.existsSync(destination) on the raw string. After resolving paths you should perform existence checks on the resolved path (e.g. destinationPath) for consistency. Also see the next comment about error handling when the directory is missing.

console.error(`Destination directory does not exist: ${destination}`);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The requirements mandate that when the intended destination directory does not exist you must throw an Error with the message Destination directory does not exist: <destinationDir> instead of logging and returning. Replace this console.error + return with throw new Error('Destination directory does not exist: ' + destinationPath) (or appropriate directory variable).


return;
Comment on lines +33 to +36

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When the intended destination directory doesn't exist you console.error(...) and return. The specification requires throwing an error here so callers/tests can detect failure (e.g. throw new Error('Destination directory does not exist: ' + destination)), not just logging and returning.

} else {
fs.writeFileSync(
path.join(destinationPath, path.basename(sourcePath)),
data,
);
}
} else if (fs.existsSync(destinationPath)) {
const stats = fs.statSync(destinationPath);

if (stats.isDirectory()) {
fs.writeFileSync(
path.join(destinationPath, path.basename(sourcePath)),
data,
);
} else {
fs.writeFileSync(destinationPath, data);
}
} else {
const destinationDir = path.dirname(destinationPath);

if (!fs.existsSync(destinationDir)) {
console.error(
`Destination directory does not exist: ${destinationDir}`,
Comment on lines +58 to +59

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same problem here: replace the console.error(...) and return with throwing an Error: throw new Error('Destination directory does not exist: ' + destinationDir) so callers/tests can detect the failure programmatically.

);

return;
Comment on lines +57 to +62

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

When the destination directory is missing you console.error(...) and return. The task requires that an error be thrown in this case. Replace the console.error + return with throwing an Error (for example: throw new Error('Destination directory does not exist: ' + destinationDir)) so callers/tests can detect the failure.

Comment on lines +57 to +62

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Same issue here: logging and returning when destinationDir does not exist. Per requirements you must throw an Error so callers/tests can observe the failure (replace console.error(...); return; with throw new Error(...)).

}

fs.writeFileSync(destinationPath, data);
}

fs.unlinkSync(sourcePath);
} catch (err) {
throw new Error(err.message);
}
};

moveFile();

module.exports = {
moveFile,
};
Loading