Skip to content
Open
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
34 changes: 34 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1 +1,35 @@
/* eslint-disable no-console */
// write code here
const fs = require('fs');
const path = require('path');

const moveFiles = () => {
const args = process.argv.slice(2);

const [fileName, newPath] = args;

Comment on lines +6 to +10

Choose a reason for hiding this comment

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

Missing source validation — must verify source exists and is a regular file.

You destructure fileName from args but never check that the path exists or is a file. The spec requires that moving directories is not supported and that missing sources produce an error. Add a const stat = fs.lstatSync(fileName) and check stat.isFile(). If it doesn't exist or !isFile, print an error and process.exit(1). This addresses: "The source must be a file; moving directories is not supported". (lines 6-10)

if (args.length < 2) {
console.error('You need fileName and destination');

return;
}
Comment on lines +11 to +15

Choose a reason for hiding this comment

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

Argument count enforcement — must accept exactly two positional arguments.

Current code uses if (args.length < 2) and then returns, which allows args.length > 2 silently and exits with code 0. The task requires exactly two positional args (no flags or extras). Change the check to if (args.length !== 2) { console.error('Usage: node index <source> <destination>'); process.exit(1); } so invalid usage returns a non-zero exit code. This satisfies: "Ensure exactly two arguments are provided" and "No additional command-line options or flags are supported." (lines 11-15)

Comment on lines +7 to +15

Choose a reason for hiding this comment

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

Silent acceptance of extra arguments — must reject extras.

The program destructures only two arguments and ignores the rest. The checker may pass extra args to validate strict parsing. Enforce args.length === 2 and exit with an error when there are more args. This enforces "no additional options or flags" requirement. (lines 7-15)


try {
const isDirectory =
fs.existsSync(newPath) && fs.lstatSync(newPath).isDirectory();

const updatedPath = isDirectory
? path.join(newPath, path.basename(fileName))
: newPath;
Comment on lines +17 to +23

Choose a reason for hiding this comment

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

Destination trailing-slash semantics and directory existence check.

Right now isDirectory is computed as fs.existsSync(newPath) && fs.lstatSync(newPath).isDirectory(), so if the user passes a destination with a trailing slash (e.g., dir/) but dir does not exist, code will not treat it as a directory and will attempt to rename to that path instead of throwing an error. The requirement is: a trailing slash must be considered a directory target and must exist. Implement explicit detection of trailing slash (e.g., const wantedAsDir = newPath.endsWith(path.sep) || newPath.endsWith('/')) and if wantedAsDir is true, check existence of the directory and error if missing. Also handle the case where newPath exists and is a directory even without trailing slash. This ensures behavior consistent with examples such as node index file.txt dir/. (lines 17-23)

Comment on lines +17 to +23

Choose a reason for hiding this comment

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

Behavior for node index file.txt a ambiguous when a exists vs not — ensure correct resolution.

The task states: if a is an existing directory, move to ./a/file.txt. If a does not exist, rename to ./a. Your current isDirectory logic handles the case when a exists and is a dir, but because you don't explicitly handle trailing-slash intent and lack source checks, edge cases can misbehave. Ensure the code first resolves whether newPath refers to a directory (existing or trailing slash) and then construct target with path.join(dir, path.basename(source)) otherwise treat newPath as a file path. (lines 17-23 and 21-23)


fs.renameSync(fileName, updatedPath);

Choose a reason for hiding this comment

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

Single fs.renameSync without EXDEV fallback — implement copy+unlink fallback.

fs.renameSync is fine for same-device moves but throws EXDEV when moving across devices. The task requires that the source be removed after a successful move; to handle cross-device cases, catch the EXDEV error and perform a fallback: fs.copyFileSync(src, dest) followed by fs.unlinkSync(src). Also ensure you clean up a partially copied destination on failure. Without this fallback cross-device moves will fail. (line 25)

} catch (error) {
console.error('Error occurred:', error);
}
Comment on lines +26 to +28

Choose a reason for hiding this comment

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

Error handling: logged errors don't cause non-zero exit.

The catch block only logs the error: console.error('Error occurred:', error); but does not process.exit(1). For a CLI, failing operations should exit with a non-zero code so callers and tests detect failure. After logging, call process.exit(1) (or rethrow) to signal failure. This also helps satisfy tests that expect the program to fail for invalid inputs (e.g., missing source or missing destination directory). (lines 26-28)

Comment on lines +11 to +28

Choose a reason for hiding this comment

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

Improve error messages and early exits for CLI clarity.

Instead of generic messages like You need fileName and destination, provide usage guidance such as Usage: node index <source> <destination> and ensure each failure path (source missing, source is directory, destination dir does not exist) prints a clear message and exits with process.exit(1). This will make the CLI behavior deterministic and testable. (lines 11-15 and 26-28)

};

moveFiles();

module.exports = {
moveFiles,
};