<commit_before>﻿using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace Webpack {
	internal class Webpack : IWebpack {

		private const string webpack = "webpack";
		private const string webpackDevServer = "webpack-dev-server";

		private readonly ILoggerFactory _loggerFactory;
		private readonly string _webRootPath;

		public Webpack(IHostingEnvironment env, ILoggerFactory loggerFactory) {
			_webRootPath = env.WebRootPath;
			_loggerFactory = loggerFactory;
		}

		public WebPackMiddlewareOptions Execute(WebpackOptions options) {
			var toolToExecute = options.EnableHotLoading ? webpackDevServer : webpack;
			var logger = _loggerFactory.CreateLogger(toolToExecute);

			logger.LogInformation($"Verifying required tools are installed");
			EnsuereNodeModluesInstalled(options.EnableHotLoading, logger);
			logger.LogInformation($"All node modules are properly installed");

			CreateWebpackConfigurationFile(options);

			logger.LogInformation($"{toolToExecute} Execution started");
			var arguments = ArgumentsHelper.GetWebpackArguments(_webRootPath, options);
			logger.LogInformation($"{toolToExecute} is called with these arguments: {arguments}");
			Process process = new Process();
			process.StartInfo = new ProcessStartInfo() {
				FileName = GetNodeExecutable(toolToExecute),
				Arguments = arguments,
				UseShellExecute = false
			};
			process.Start();
			logger.LogInformation($"{toolToExecute} started successfully");

			return new WebPackMiddlewareOptions {
				EnableHotLoading = options.EnableHotLoading,
				OutputFileName = options.OutputFileName,
				Host = options.DevServerOptions.Host,
				Port = options.DevServerOptions.Port
			};
		}

		public WebPackMiddlewareOptions Execute(string configFile, string outputFileName, WebpackDevServerOptions devServerOptions) {
			var enableHotLoading = devServerOptions != null;
			var toolToExecute = enableHotLoading ? webpackDevServer : webpack;
			var logger = _loggerFactory.CreateLogger(toolToExecute);

			logger.LogInformation($"Verifying required tools are installed");
			EnsuereNodeModluesInstalled(enableHotLoading, logger);
			logger.LogInformation($"All node modules are properly installed");

			logger.LogInformation($"{toolToExecute} Execution started");
			var arguments = $"--config {configFile}";

			logger.LogInformation($"{toolToExecute} is called with these arguments: {arguments}");
			Process process = new Process();
			process.StartInfo = new ProcessStartInfo() {
				FileName = GetNodeExecutable(toolToExecute),
				Arguments = arguments,
				UseShellExecute = false
			};
			process.Start();
			logger.LogInformation($"{toolToExecute} started successfully");

			var middleWareOptions = new WebPackMiddlewareOptions {
				OutputFileName = outputFileName,
				EnableHotLoading = enableHotLoading
			};
			if (enableHotLoading) {
				middleWareOptions.Host = devServerOptions.Host;
				middleWareOptions.Port = devServerOptions.Port;
			}

			return middleWareOptions;
		}

		private static void EnsuereNodeModluesInstalled(bool enableHotLoading, ILogger logger) {
			if (!File.Exists(GetNodeExecutable(webpack))) {
				logger.LogError("webpack is not installed. Please install it by executing npm i webpack");
			}
			if (enableHotLoading && !File.Exists(GetNodeExecutable(webpackDevServer))) {
				logger.LogError("webpack-dev-server is not installed. Please install it by executing npm i webpack-dev-server");
			}
		}

		private static string GetNodeExecutable(string module) {
			var executable = Path.Combine(Directory.GetCurrentDirectory(), "node_modules", ".bin", module);
			var osEnVariable = Environment.GetEnvironmentVariable("OS");
			if (!string.IsNullOrEmpty(osEnVariable) && string.Equals(osEnVariable, "Windows_NT", StringComparison.OrdinalIgnoreCase)) {
				executable += ".cmd";
			}
			return executable;
		}

		private static void CreateWebpackConfigurationFile(WebpackOptions options) {
			if (!Directory.Exists("webpack")) {
				Directory.CreateDirectory("webpack");
			}
			var presets = new List<string>() {
				"es2015"
			};
			if (options.HandleJsxFiles) {
				presets.Add("react");
			}
			var query = new Query {
				Presets = presets
			};
			var loaders = new List<WebpackLoader>();
			if (options.EnableES2015) {
				loaders.Add(new WebpackLoader {
					Test = "/\\.js/",
					Loader = "babel-loader",
					Exclude = "/node_modules/",
					Query = query
				});
			}
			if (options.HandleJsxFiles) {
				loaders.Add(new WebpackLoader {
					Test = "/\\.jsx/",
					Loader = "babel-loader",
					Exclude = "/node_modules/",
					Query = query
				});
			}
			var exports = new {
				module = new {
					loaders
				}
			};
			var jsonResult = JsonConvert.SerializeObject(exports,
				new JsonSerializerSettings {
					Formatting = Formatting.Indented,
					ContractResolver = new CamelCasePropertyNamesContractResolver()
				});
			var fileContent = $"module.exports = {jsonResult}";
			using (var fs = File.Create(Path.Combine("webpack", "webpack.dev.js"))) {
				using (var streamWriter = new StreamWriter(fs)) {
					streamWriter.WriteLine(fileContent);
				}
			}
		}

	}
}<commit_msg>#7 Create an external configuration file for webpack only if is needed<commit_after>﻿using Microsoft.AspNet.Hosting;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;

namespace Webpack {
	internal class Webpack : IWebpack {

		private const string webpack = "webpack";
		private const string webpackDevServer = "webpack-dev-server";

		private readonly ILoggerFactory _loggerFactory;
		private readonly string _webRootPath;

		public Webpack(IHostingEnvironment env, ILoggerFactory loggerFactory) {
			_webRootPath = env.WebRootPath;
			_loggerFactory = loggerFactory;
		}

		public WebPackMiddlewareOptions Execute(WebpackOptions options) {
			var toolToExecute = options.EnableHotLoading ? webpackDevServer : webpack;
			var logger = _loggerFactory.CreateLogger(toolToExecute);

			logger.LogInformation($"Verifying required tools are installed");
			EnsuereNodeModluesInstalled(options.EnableHotLoading, logger);
			logger.LogInformation($"All node modules are properly installed");

			CreateWebpackConfigurationFile(options);

			logger.LogInformation($"{toolToExecute} Execution started");
			var arguments = ArgumentsHelper.GetWebpackArguments(_webRootPath, options);
			logger.LogInformation($"{toolToExecute} is called with these arguments: {arguments}");
			Process process = new Process();
			process.StartInfo = new ProcessStartInfo() {
				FileName = GetNodeExecutable(toolToExecute),
				Arguments = arguments,
				UseShellExecute = false
			};
			process.Start();
			logger.LogInformation($"{toolToExecute} started successfully");

			return new WebPackMiddlewareOptions {
				EnableHotLoading = options.EnableHotLoading,
				OutputFileName = options.OutputFileName,
				Host = options.DevServerOptions.Host,
				Port = options.DevServerOptions.Port
			};
		}

		public WebPackMiddlewareOptions Execute(string configFile, string outputFileName, WebpackDevServerOptions devServerOptions) {
			var enableHotLoading = devServerOptions != null;
			var toolToExecute = enableHotLoading ? webpackDevServer : webpack;
			var logger = _loggerFactory.CreateLogger(toolToExecute);

			logger.LogInformation($"Verifying required tools are installed");
			EnsuereNodeModluesInstalled(enableHotLoading, logger);
			logger.LogInformation($"All node modules are properly installed");

			logger.LogInformation($"{toolToExecute} Execution started");
			var arguments = $"--config {configFile}";

			logger.LogInformation($"{toolToExecute} is called with these arguments: {arguments}");
			Process process = new Process();
			process.StartInfo = new ProcessStartInfo() {
				FileName = GetNodeExecutable(toolToExecute),
				Arguments = arguments,
				UseShellExecute = false
			};
			process.Start();
			logger.LogInformation($"{toolToExecute} started successfully");

			var middleWareOptions = new WebPackMiddlewareOptions {
				OutputFileName = outputFileName,
				EnableHotLoading = enableHotLoading
			};
			if (enableHotLoading) {
				middleWareOptions.Host = devServerOptions.Host;
				middleWareOptions.Port = devServerOptions.Port;
			}

			return middleWareOptions;
		}

		private static void EnsuereNodeModluesInstalled(bool enableHotLoading, ILogger logger) {
			if (!File.Exists(GetNodeExecutable(webpack))) {
				logger.LogError("webpack is not installed. Please install it by executing npm i webpack");
			}
			if (enableHotLoading && !File.Exists(GetNodeExecutable(webpackDevServer))) {
				logger.LogError("webpack-dev-server is not installed. Please install it by executing npm i webpack-dev-server");
			}
		}

		private static string GetNodeExecutable(string module) {
			var executable = Path.Combine(Directory.GetCurrentDirectory(), "node_modules", ".bin", module);
			var osEnVariable = Environment.GetEnvironmentVariable("OS");
			if (!string.IsNullOrEmpty(osEnVariable) && string.Equals(osEnVariable, "Windows_NT", StringComparison.OrdinalIgnoreCase)) {
				executable += ".cmd";
			}
			return executable;
		}

		private static void CreateWebpackConfigurationFile(WebpackOptions options) {
			if (!Directory.Exists("webpack")) {
				Directory.CreateDirectory("webpack");
			}
			var presets = new List<string>() {
				"es2015"
			};
			if (options.HandleJsxFiles) {
				presets.Add("react");
			}
			var query = new Query {
				Presets = presets
			};
			var loaders = new List<WebpackLoader>();
			if (options.EnableES2015) {
				loaders.Add(new WebpackLoader {
					Test = "/\\.js/",
					Loader = "babel-loader",
					Exclude = "/node_modules/",
					Query = query
				});
			}
			if (options.HandleJsxFiles) {
				loaders.Add(new WebpackLoader {
					Test = "/\\.jsx/",
					Loader = "babel-loader",
					Exclude = "/node_modules/",
					Query = query
				});
			}
			var exports = new {
				module = new {
					loaders
				}
			};
			// Create the external configuration file only if we need to use babel-loader
			if (loaders.Count > 0) {
				var jsonResult = JsonConvert.SerializeObject(exports,
					new JsonSerializerSettings {
						Formatting = Formatting.Indented,
						ContractResolver = new CamelCasePropertyNamesContractResolver()
					});
				var fileContent = $"module.exports = {jsonResult}";
				using (var fs = File.Create(Path.Combine("webpack", "webpack.dev.js"))) {
					using (var streamWriter = new StreamWriter(fs)) {
						streamWriter.WriteLine(fileContent);
					}
				}
			}
		}

	}
}
{'fraction_non_alphanumeric': 0.10304493130337913, 'fraction_numerical': 0.0016709988860007428, 'mean_word_length': 4.330529440870856, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 8, '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': '2061892', 'n_tokens_mistral': 3613, 'n_tokens_neox': 2981, 'n_words': 700}