<commit_before>const { join } = require('path');

const { isWindows, setTimeoutPromise } = require('../util');
const { lstat, unlink, rmdir, chmod, readdir } = require('../fs');

/**
 * @typedef {Object} RemoveOptions
 * @memberof fsn/nextra
 * @property {number} [maxBusyTries = 3] The number of times fs-nextra should retry removing a busy file.
 */

/**
 * Removes a single file or single directory with no children.
 * @function remove
 * @memberof fsn/nextra
 * @param {string} path The path to remove
 * @param {RemoveOptions} [options = {}] {description}
 * @returns {Promise<void>}
 */
const remove = module.exports = async function remove(path, options = {}) {
	if (typeof path !== 'string') throw new Error('Path should be a string');
	options.maxBusyTries = typeof options.maxBusyTries === 'undefined' ? 3 : options.maxBusyTries;

	for (let buysTries = 0; buysTries < options.maxBusyTries; buysTries++) {
		try {
			await rimraf(path, options);
			break;
		} catch (err) {
			// Windows
			/* istanbul ignore next */
			if (isWindows && (err.code === 'EBUSY' || err.code === 'ENOTEMPTY' || err.code === 'EPERM')) {
				await setTimeoutPromise(buysTries * 100);
				continue;
			}
			// Hard to test via travis, such as ENOMEM (running the kernel out of memory)
			/* istanbul ignore else */
			if (err.code === 'ENOENT') return;
			else throw err;
		}
	}
};

const rimraf = async (myPath, options) => {
	try {
		const stats = await lstat(myPath);
		if (stats.isDirectory()) return removeDir(myPath, options);
	} catch (err) {
		// Windows
		/* istanbul ignore next */
		if (isWindows && err.code === 'EPERM') return fixWinEPERM(myPath, options);
		throw err;
	}

	try {
		return await unlink(myPath);
	} catch (er) {
		// Windows
		/* istanbul ignore next */
		if (er.code === 'EPERM') return isWindows ? fixWinEPERM(myPath, options, er) : removeDir(myPath, options, er);
		// Difficult to reproduce
		/* istanbul ignore next */<commit_msg>fix superfluous argument<commit_after>const { join } = require('path');

const { isWindows, setTimeoutPromise } = require('../util');
const { lstat, unlink, rmdir, chmod, readdir } = require('../fs');

/**
 * @typedef {Object} RemoveOptions
 * @memberof fsn/nextra
 * @property {number} [maxBusyTries = 3] The number of times fs-nextra should retry removing a busy file.
 */

/**
 * Removes a single file or single directory with no children.
 * @function remove
 * @memberof fsn/nextra
 * @param {string} path The path to remove
 * @param {RemoveOptions} [options = {}] {description}
 * @returns {Promise<void>}
 */
const remove = module.exports = async function remove(path, options = {}) {
	if (typeof path !== 'string') throw new Error('Path should be a string');
	options.maxBusyTries = typeof options.maxBusyTries === 'undefined' ? 3 : options.maxBusyTries;

	for (let buysTries = 0; buysTries < options.maxBusyTries; buysTries++) {
		try {
			await rimraf(path, options);
			break;
		} catch (err) {
			// Windows
			/* istanbul ignore next */
			if (isWindows && (err.code === 'EBUSY' || err.code === 'ENOTEMPTY' || err.code === 'EPERM')) {
				await setTimeoutPromise(buysTries * 100);
				continue;
			}
			// Hard to test via travis, such as ENOMEM (running the kernel out of memory)
			/* istanbul ignore else */
			if (err.code === 'ENOENT') return;
			else throw err;
		}
	}
};

const rimraf = async (myPath, options) => {
	try {
		const stats = await lstat(myPath);
		if (stats.isDirectory()) return removeDir(myPath, options);
	} catch (err) {
		// Windows
		/* istanbul ignore next */
		if (isWindows && err.code === 'EPERM') return fixWinEPERM(myPath, options);
		throw err;
	}

	try {
		return await unlink(myPath);
	} catch (er) {
		// Windows
		/* istanbul ignore next */
		if (er.code === 'EPERM') return isWindows ? fixWinEPERM(myPath, options) : removeDir(myPath, options, er);
		// Difficult to reproduce
		/* istanbul ignore next */
{'fraction_non_alphanumeric': 0.15118956254796623, 'fraction_numerical': 0.0030698388334612432, 'mean_word_length': 3.632701421800948, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3584493', 'n_tokens_mistral': 1391, 'n_tokens_neox': 1288, 'n_words': 393}