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
23 changes: 23 additions & 0 deletions .github/workflows/test.yml-template
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
name: Test

on:
pull_request:
branches: [ master ]

jobs:
build:

runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20.x]

steps:
- uses: actions/checkout@v2
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- run: npm install
- run: npm test
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
56 changes: 56 additions & 0 deletions src/app.js
Original file line number Diff line number Diff line change
@@ -1 +1,57 @@
/* eslint-disable no-console */
'use strict';

const fs = require('fs');

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

To compare resolved paths correctly and handle symlinks, also require path (e.g. const path = require('path')) and use fs.realpathSync on the source and, if the destination exists, on the destination too. If the destination does not exist use path.resolve(dest) rather than realpath (realpathSync throws for non-existent paths).

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 need to require the path module (e.g. const path = require('path')) because the specification requires using path.resolve(dest) when the destination does not exist before comparing paths.


const copy = () => {
const [src, dest] = process.argv.slice(2);

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

return;
}

if (!fs.existsSync(src)) {
console.error(`Source file does not exist: ${src}`);

return;
}

const srcStats = fs.statSync(src);

if (!srcStats.isFile()) {
console.error(`Source must be a file: ${src}`);

return;
}

if (fs.existsSync(dest)) {
const destStats = fs.statSync(dest);

if (destStats.isDirectory()) {
console.error(`Destination cannot be a directory: ${dest}`);

return;
}
}

if (src === dest) {
return;
Comment on lines +39 to +40

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Checklist items #2, #7 and #8 require that when source and destination refer to the same file the app must do nothing (no console output). Here you log an error and return. Instead, resolve/normalize both paths (for example with fs.realpathSync or path.resolve + fs.realpathSync) and perform a silent early return when they match.

Comment on lines +39 to +40

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 raw comparison if (src === dest) is insufficient. Per the guideline, resolve/normalize both paths: use fs.realpathSync(src) for the source (after verifying it exists) and for the destination use fs.realpathSync(dest) if it exists, otherwise path.resolve(dest). If the resolved paths are equal, perform an early return with NO console output. This implements the required silent no-op for same-file cases (checklist items #2 and #8).

}

const data = fs.readFileSync(src);

try {
fs.writeFileSync(dest, data);
console.log(`File copied from ${src} to ${dest}`);
} catch (err) {
console.error(`Error writing to destination: ${err.message}`);
}
};

copy();

module.exports = {
copy,
};
Loading