Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
38 changes: 29 additions & 9 deletions src/mvnw.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const path = require('path');
const fs = require('fs');
const rel = require('relative');
const readline = require('readline');
const {spawn} = require('child_process');
const { spawn } = require('child_process');
const colors = require('colors');

/**
Expand All @@ -30,7 +30,7 @@ let beginning,
* @param {Object} opts - Opts provided to the "eoc"
* @return {Array} of Maven options
*/
module.exports.flags = function(opts) {
module.exports.flags = function (opts) {
const sources = path.resolve(opts.sources);
console.debug('Sources in %s', rel(sources));
const target = path.resolve(opts.target);
Expand Down Expand Up @@ -58,7 +58,7 @@ module.exports.flags = function(opts) {
* @param {Boolean} [batch] - Is it batch mode (TRUE) or interactive (FALSE)?
* @return {Promise} of maven execution task
*/
module.exports.mvnw = function(args, tgt, batch) {
module.exports.mvnw = function (args, tgt, batch) {
return new Promise((resolve, reject) => {
target = tgt;
phase = args[0];
Expand All @@ -71,7 +71,7 @@ module.exports.mvnw = function(args, tgt, batch) {
'--fail-fast',
'--strict-checksums',
]),
cmd = `${bin } ${ params.join(' ')}`;
cmd = `${bin} ${params.join(' ')}`;
console.debug('+ %s', cmd);
const result = spawn(
bin,
Expand Down Expand Up @@ -114,7 +114,7 @@ module.exports.mvnw = function(args, tgt, batch) {
function start() {
running = true;
beginning = Date.now();
const check = function() {
const check = function () {
if (running) {
print();
setTimeout(check, 1000);
Expand Down Expand Up @@ -143,14 +143,34 @@ function print() {
* @return {Integer} Total number files.
*/
function count(dir, curr) {
if (fs.existsSync(dir)) {
for (const f of fs.readdirSync(dir)) {
const next = path.join(dir, f);
if (fs.statSync(next).isDirectory()) {
if (!fs.existsSync(dir)) {
return curr;
}
let files;
try {
files = fs.readdirSync(dir);
} catch (err) {
if (err.code === 'ENOENT') {
return curr;
}
throw err;
}

for (const f of files) {
const next = path.join(dir, f);
try {
const stats = fs.statSync(next);
if (stats.isDirectory()) {
curr = count(next, curr);
} else {
curr++;
}
} catch (err) {
if (err.code === 'ENOENT') {
// ignore
} else {
throw err;
}
}
}
return curr;
Expand Down
37 changes: 35 additions & 2 deletions test/test_mvnw.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@
* SPDX-License-Identifier: MIT
*/

const {mvnw, flags} = require('../src/mvnw');
const { mvnw, flags } = require('../src/mvnw');
const assert = require('assert');
const fs = require('fs');
const path = require('path');
const os = require('os');

describe('mvnw', () => {
it('prints Maven own version', (done) => {
const opts = {batch: true};
const opts = { batch: true };
mvnw(['--version', '--quiet'], null, opts.batch);
done();
});
Expand All @@ -25,4 +28,34 @@ describe('mvnw', () => {
done();
});
});
it('handles race condition when files are deleted during counting', (done) => {
// Create a temporary directory for testing
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.

@karishka1222 we don't appreciate comments inside method bodies and we don't use blank lines inside methods. You can use this prompt: https://github.com/yegor256/prompt

const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'eoc-test-'));
const subDir = path.join(tmpDir, 'subdir');
fs.mkdirSync(subDir);

// Create some test files
fs.writeFileSync(path.join(tmpDir, 'file1.txt'), 'test');
fs.writeFileSync(path.join(subDir, 'file2.txt'), 'test');

// Simulate the count function behavior by accessing the internal function
// We'll test this indirectly by calling mvnw with a target that has files
const opts = {
sources: 'sources',
target: tmpDir,
parser: 'parser',
homeTag: 'homeTag'
};

// This should not throw an error even if files are deleted during execution
mvnw(['--version', '--quiet', ...flags(opts)]).then(() => {
// Clean up
fs.rmSync(tmpDir, { recursive: true, force: true });
done();
}).catch((err) => {
// Clean up even if test fails
fs.rmSync(tmpDir, { recursive: true, force: true });
done(err);
});
});
});