<commit_before>'use strict';
const semver = require('semver');
const detectIndent = require('detect-indent');
const parseArgs = require('yargs-parser');

const fix = (ctx, method) => {
	return () => {
		const fixers = {
			esnext: pkg => {
				if (!pkg.xo) {
					pkg.xo = {};
				}

				pkg.xo.esnext = true;
			},
			script: pkg => {
				if (!pkg.scripts) {
					pkg.scripts = {};
				}

				if (pkg.scripts.test && pkg.scripts.test.length !== 0 && pkg.scripts.test.indexOf('exit 1') === -1) {
					pkg.scripts.test = `xo && ${pkg.scripts.test}`;
				} else {
					pkg.scripts.test = `xo`;
				}
			},
			clioptions: pkg => {
				const regex = /\bxo\b([^&]*)/;

				const command = pkg.scripts.test.match(regex)[1];
				const args = parseArgs(command.trim());

				delete args._;

				pkg.xo = Object.assign({}, pkg.xo, args);
				pkg.scripts.test = pkg.scripts.test.replace(regex, 'xo ').trim();
			}
		};

		return ctx.fs.readFile('package.json', false)
			.then(pkg => {
				// Detect formatting options
				const indentation = detectIndent(pkg).indent;
				const lastchar = pkg.split('\n').pop().trim().length === 0 ? '\n' : '';

				pkg = JSON.parse(pkg);

				fixers[method](pkg);

				const contents = JSON.stringify(pkg, undefined, indentation);
				return ctx.fs.writeFile('package.json', `${contents}${lastchar}`, 'utf8');
			});
	};
};

module.exports = ctx => {
	const requiredVersion = ctx.options[0];
	const file = ctx.fs.resolve('package.json');

	return ctx.fs.readFile('package.json').then(pkg => {
		const installedVersion = pkg.devDependencies && pkg.devDependencies.xo;

		if (!installedVersion) {
			return {
				message: 'XO is not installed as devDependency.',
				file
			};
		}

		const errors = [];

		if (pkg.engines && pkg.engines.node && !semver.satisfies('0.0.10', pkg.engines.node) && !semver.satisfies('0.0.12', pkg.engines.node)) {
			if (!pkg.xo || pkg.xo.esnext !== true) {
				errors.push({
					message: 'Enforce ES2015+ rules in XO with the `esnext` option.',
					fix: fix(ctx, 'esnext'),
					file
				});
			}
		}

		if (requiredVersion) {
			if (requiredVersion === '*' && installedVersion !== '*') {
				errors.push({
					message: `Expected unicorn version '*' but found '${installedVersion}'.`,<commit_msg>fix `xo/esnext` rule - fixes #37<commit_after>'use strict';
const semver = require('semver');
const detectIndent = require('detect-indent');
const parseArgs = require('yargs-parser');

const fix = (ctx, method) => {
	return () => {
		const fixers = {
			esnext: pkg => {
				if (!pkg.xo) {
					pkg.xo = {};
				}

				pkg.xo.esnext = true;
			},
			script: pkg => {
				if (!pkg.scripts) {
					pkg.scripts = {};
				}

				if (pkg.scripts.test && pkg.scripts.test.length !== 0 && pkg.scripts.test.indexOf('exit 1') === -1) {
					pkg.scripts.test = `xo && ${pkg.scripts.test}`;
				} else {
					pkg.scripts.test = `xo`;
				}
			},
			clioptions: pkg => {
				const regex = /\bxo\b([^&]*)/;

				const command = pkg.scripts.test.match(regex)[1];
				const args = parseArgs(command.trim());

				delete args._;

				pkg.xo = Object.assign({}, pkg.xo, args);
				pkg.scripts.test = pkg.scripts.test.replace(regex, 'xo ').trim();
			}
		};

		return ctx.fs.readFile('package.json', false)
			.then(pkg => {
				// Detect formatting options
				const indentation = detectIndent(pkg).indent;
				const lastchar = pkg.split('\n').pop().trim().length === 0 ? '\n' : '';

				pkg = JSON.parse(pkg);

				fixers[method](pkg);

				const contents = JSON.stringify(pkg, undefined, indentation);
				return ctx.fs.writeFile('package.json', `${contents}${lastchar}`, 'utf8');
			});
	};
};

module.exports = ctx => {
	const requiredVersion = ctx.options[0];
	const file = ctx.fs.resolve('package.json');

	return ctx.fs.readFile('package.json').then(pkg => {
		const installedVersion = pkg.devDependencies && pkg.devDependencies.xo;

		if (!installedVersion) {
			return {
				message: 'XO is not installed as devDependency.',
				file
			};
		}

		const errors = [];

		if (pkg.engines && pkg.engines.node && !semver.satisfies('0.10.0', pkg.engines.node) && !semver.satisfies('0.12.0', pkg.engines.node)) {
			if (!pkg.xo || pkg.xo.esnext !== true) {
				errors.push({
					message: 'Enforce ES2015+ rules in XO with the `esnext` option.',
					fix: fix(ctx, 'esnext'),
					file
				});
			}
		}

		if (requiredVersion) {
			if (requiredVersion === '*' && installedVersion !== '*') {
				errors.push({
					message: `Expected unicorn version '*' but found '${installedVersion}'.`,
{'fraction_non_alphanumeric': 0.19513812154696134, 'fraction_numerical': 0.008839779005524863, 'mean_word_length': 2.977152899824253, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 19, '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': '7406599', 'n_tokens_mistral': 1933, 'n_tokens_neox': 1546, 'n_words': 317}