Beispiel #1
0
        public static void Main(string[] argv, IFileWriter fileWriter)
        {
            _fileWriter = fileWriter ?? throw new ArgumentNullException(nameof(fileWriter));
            _logger     = new Logger(fileWriter);
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);

            _openSolution  = true;
            _createMsBuild = false;
            var    _printVersion  = false;
            var    _printHelp     = false;
            var    quiteExecution = false;
            var    autoUpdateNuGetDependencies = true;
            var    nugetForceMinVersion        = true;
            var    loadUserFile         = true;
            bool   offlineMode          = false;
            string nuspecDir            = null;
            var    dump                 = false;
            var    dumpProjectStructure = false;
            var    keepGenerated        = false;
            string slnxFile             = null;

            _pythonEnvVarsPath = null;

            OptionSet p = new OptionSet()
                          .Add("h|help", "Prints the list of command and exits.", v => _printHelp = v != null)
                          .Add("v|version", "Prints the tool version in the standard output and exits.", v => _printVersion = v != null)
                          .Add("q|quite", "If set (-q/-q+) no popup will be shown in case of exceptions. [Default: not set]", v => quiteExecution = v != null)
                          .Add("<>", "SlnX file path", v => slnxFile = v)
                          .Add("o|openSln", "If set (-o/-o+) opens the generated Sln file. If not set (-o-), the generated Sln will not be opened. [Default: set]", v => _openSolution = v != null)
                          .Add("u|user", "If set (-u/-u+) it loads an eventually present .user file. [Default: set]", v => loadUserFile = v != null)
                          .Add("d|dump", "If set (-d/-d+) it dumps all project paths and environment variables in dump.txt located in the SlnX location. [Default: not set]", v => dump            = v != null)
                          .Add("p|slnxProjects", "If set (-p/-p+) it creates a SlnX file with all project and their reference in the SlnX location. [Default: not set]", v => dumpProjectStructure = v != null)
                          .Add("k|keepGenerated", "If set (-k/-k+) it prevent the cleanup of all the slnx.config generated files. Note: this doesn't prevent the files to be overwritten. [Default: not set]", v => keepGenerated = v != null)
                          .Add("py=|pythonModule=", "Path for the python module. If set the specified python module containing all defined environment variables is created. [Default: not set]", v => _pythonEnvVarsPath         = v)
                          .Add("b=|batchModule=", "Path to the batch module. If set the specified batch module containing all defined environment variables is created. [Default: not set]", v => _batchEnvVarsPath = v)
                          .Add("ps=|powershellModule=", "Path to the power-shell module. If set the specified power-shell module containing all defined environment variables is created. [Default: not set]", v => _psEnvVarsPath = v)
                          .Add("msb|msbuildModule", "If set (-msb/-msb+) a MSBuild module containing all defined environment variables is created in the SlnX location. [Default: not set]", v => _createMsBuild = v != null)
                          .Add("log", "If set (-log/-log+), a log file location in the SlnX directory (or EXE if that path is invalid) will be created. [Default: false]", v => _logEnabled = v != null)
                          .Add("lv=|logVerbosity=", string.Format("Set the log level of verbosity. Valid values {0}. [Default: {1}]", string.Join(",", Enum.GetNames <LogLevel>()), _logLevel), v => _logLevel = ParseLogLevel(v))
                          .Add("ns=|nuspec=", "Output path for the NuGet package created based on the current solution. [Default: not set]", v => nuspecDir = v)
                          .Add("nd|nugetDependencies", "If set (-nd/-nd+), the dependencies of the provided packages will be also automatically downloaded. [Default: true]", v => autoUpdateNuGetDependencies = v != null)
                          .Add("offline", "If set (-offline/-offline+), The current SlnX packagesPath attribute will be used as source for all packages. [Default: false]", v => offlineMode = v != null)
                          .Add("nf|nugetForceMinVersion", "If set (-nf/-nf+), the tool will check that dependencies fulfill the min-version provided (not allowing newer versions). [Default: true]", v => nugetForceMinVersion = v != null);

            try
            {
                p.Parse(argv);
                if (_printVersion)
                {
                    Console.WriteLine("SlnLauncher v{0}", typeof(SlnxHandler).Assembly.GetName().Version.ToString(3));
                    return;
                }
                if (_printHelp)
                {
                    Console.WriteLine("SlnLauncher v{0}", typeof(SlnxHandler).Assembly.GetName().Version.ToString(3));
                    p.WriteOptionDescriptions(Console.Out);
                    return;
                }

                if (slnxFile == null)
                {
                    throw new ArgumentException(string.Format("Invalid parameters, no SlnX file specified.\n\n\t{0}", string.Join("\n\t", argv)));
                }

                slnxFile = Path.GetFullPath(Environment.ExpandEnvironmentVariables(slnxFile));
                if (File.Exists(slnxFile))
                {
                    Environment.CurrentDirectory = Path.GetDirectoryName(slnxFile);
                }
                if (_logEnabled)
                {
                    _logger.SetLog(Path.Join(Environment.CurrentDirectory, Path.GetFileNameWithoutExtension(typeof(Program).Assembly.Location) + ".log"), _logLevel);
                    NuGetClientHelper.NuGetClientHelper.SetLogger(_logger);
                }
                _logger.Info("Application started with parameters: {0}", string.Join("\n", argv));

                var slnxUserFile = string.Format("{0}{1}", slnxFile, SlnxHandler.SlnxUserExtension);

                SlnXType slnxUser = null;

                if (loadUserFile && File.Exists(slnxUserFile))
                {
                    slnxUser = SlnxHandler.ReadSlnx(slnxUserFile);
                }

                var  slnx = new SlnxHandler(slnxFile, slnxUser, _fileWriter, _logger, null, offlineMode);
                var  originalPackageList = new List <NuGetClientHelper.NuGetPackage>(slnx.Packages);
                bool errorOccured        = false;
                try
                {
                    DownloadPackages(slnx, quiteExecution, autoUpdateNuGetDependencies);

                    if (_createMsBuild)
                    {
                        CreateMsBuildPropertiesTarget(slnx);
                    }

                    if (!string.IsNullOrEmpty(_pythonEnvVarsPath))
                    {
                        CreatePythonnModule(slnx, Path.Combine(slnx.SlnxDirectory, _pythonEnvVarsPath));
                    }
                    if (!string.IsNullOrEmpty(_batchEnvVarsPath))
                    {
                        CreateBatchModule(slnx, Path.Combine(slnx.SlnxDirectory, _batchEnvVarsPath));
                    }
                    if (!string.IsNullOrEmpty(_psEnvVarsPath))
                    {
                        CreatePowerShellModule(slnx, Path.Combine(slnx.SlnxDirectory, _psEnvVarsPath));
                    }

                    var ignoreDependencyCheck = !autoUpdateNuGetDependencies;
                    _logger.Info($"Running dependency check with force min-version match set to {nugetForceMinVersion}, and ignore dependency is {ignoreDependencyCheck}");
                    NuGetClientHelper.NuGetClientHelper.CheckPackagesConsistency(slnx.Packages.ToList(), nugetForceMinVersion, ignoreDependencyCheck);

                    _logger.Info($"Checking debug packages consistency...");

                    foreach (var debugPackage in slnx.DebugSlnxItems.Keys)
                    {
                        foreach (var package in slnx.Packages)
                        {
                            if (package.Dependencies.Where(x => x.PackageDependency.Id.Equals(debugPackage.Identity.Id, StringComparison.OrdinalIgnoreCase)).Any())
                            {
                                _logger.Warn($"{package} depends on the package {debugPackage.Identity.Id} which is selected for debugging. This might cause runtime issues! Consider marking it for debugging as well.");
                            }
                        }
                    }

                    _logger.Info($"Check if all packages that are bind via .NET ImplementationAssemblies (lib directory) are specified in the SlnX file");
                    foreach (var package in slnx.Packages.Where((x) => x.PackageType == NuGetClientHelper.NuGetDotNetPackageType.DotNetImplementationAssembly))
                    {
                        if (!originalPackageList.Where((x) => x.Identity.Id.Equals(package.Identity.Id, StringComparison.OrdinalIgnoreCase)).Any())
                        {
                            _logger.Info($"The .NET implementation package {package} has been installed as dependency. Consider define it explicitly. Execute a dump to analyze dependency graph.");
                        }
                    }

                    _logger.Info($"Check if all packages that are bind via .NET CompileTimeAssemblies (ref directory) are specified in the SlnX file");
                    foreach (var package in slnx.Packages.Where((x) => x.PackageType == NuGetClientHelper.NuGetDotNetPackageType.DotNetCompileTimeAssembly))
                    {
                        if (originalPackageList.Where((x) => x.Identity.Id.Equals(package.Identity.Id, StringComparison.OrdinalIgnoreCase)).FirstOrDefault() == default(NuGetPackage))
                        {
                            _logger.Info($"The .NET compile time package {package} has been installed as dependency.");
                        }
                    }

                    MakeSln(slnx);

                    if (!keepGenerated)
                    {
                        slnx.CleanGenereatedFilesRecurisvely();
                    }
                    slnx.CreateGenereatedFilesRecurisvely();

                    if (!string.IsNullOrEmpty(nuspecDir))
                    {
                        nuspecDir = Path.GetFullPath(slnx.SafeExpandEnvironmentVariables(nuspecDir));
                        if (nuspecDir == slnx.SlnxDirectory)
                        {
                            throw new Exception($"The provided nuspec directory is the same as the slnx folder. Please specify a sub folder.");
                        }
                        if (!Directory.Exists(nuspecDir))
                        {
                            Directory.CreateDirectory(nuspecDir);
                        }
                        else
                        {
                            if (Directory.EnumerateFileSystemEntries(nuspecDir).Any())
                            {
                                throw new Exception($"The provided nuspec directory is not empty: '{nuspecDir}'");
                            }
                        }
                        var nuspec = slnx.GetNuGetPackageInformation();
                        if (nuspec != null)
                        {
                            NuGetClientHelper.NuspecGenerator.Generate(nuspecDir, nuspec);
                        }
                        else
                        {
                            throw new Exception("Missing or invalid nuget content information in the provided SlnX file.");
                        }
                    }

                    if (dumpProjectStructure)
                    {
                        DumpProjectSlnx(slnx);
                    }
                }
                catch
                {
                    errorOccured = true;
                    throw;
                }
                finally
                {
                    if (dump)
                    {
                        Dump(slnx, errorOccured);
                    }
                }

                if (_logger.LogLevelDetected(LogLevel.Warning))
                {
                    if (!quiteExecution)
                    {
                        var    baseMsg = $"Warning(s) detected. This could cause runtime issues.\nIt's highly suggested to";
                        string message = "";
                        if (_logEnabled)
                        {
                            message = $"{baseMsg} review them in the log file: {_logger.LogPath}";
                        }
                        else
                        {
                            message = $"{baseMsg} re-run the application with log turned on.";
                        }
                        new InfoBox("Warning", message, System.Drawing.SystemIcons.Warning.ToBitmap()).ShowDialog();
                    }
                }
                _logger.Info($"Done!");

                if (_openSolution)
                {
                    OpenSln(slnx.SlnPath);
                }
            }
            catch (Exception ex)
            {
                string exText     = "";
                var    stackTrace = ex.StackTrace;
                while (ex != null)
                {
                    exText = string.Join("\n", ex.Message);
                    ex     = ex.InnerException;
                }
                _logger.Error(exText);
                _logger.Error(stackTrace);

                if (!quiteExecution)
                {
                    string message;
                    if (_logEnabled)
                    {
                        message = $"Inspect the log for more information.\nLog file: {_logger.LogPath}\n\n{exText}";
                    }
                    else
                    {
                        message = $"Re-run the application with log turned on (--log) for more information\n\n{exText}";
                    }
                    new InfoBox("Error", message, System.Drawing.SystemIcons.Error.ToBitmap()).ShowDialog();
                }
                else
                {
                    throw;
                }
            }
        }