Exemplo n.º 1
0
        public void ThrowsWhenRootDoesNotExist()
        {
            var files  = new TemporaryFileProvider();
            var finder = new MsBuildProjectFinder(files.Root);

            files.Dispose();
            Assert.Throws <FileNotFoundException>(() => finder.FindMsBuildProject(null));
        }
Exemplo n.º 2
0
        public void ThrowsWhenFileDoesNotExist()
        {
            using (var files = new TemporaryFileProvider())
            {
                var finder = new MsBuildProjectFinder(files.Root);

                Assert.Throws <FileNotFoundException>(() => finder.FindMsBuildProject("test.csproj"));
            }
        }
        public void ThrowsWhenNoFile()
        {
            using (var files = new TemporaryFileProvider())
            {
                var finder = new MsBuildProjectFinder(files.Root);

                Assert.Throws <InvalidOperationException>(() => finder.FindMsBuildProject());
            }
        }
Exemplo n.º 4
0
        public void ThrowsWhenNoFile()
        {
            using (var files = new TemporaryFileProvider())
            {
                var finder = new MsBuildProjectFinder(files.Root);

                Assert.Throws <FileNotFoundException>(() => finder.FindMsBuildProject(null));
            }
        }
Exemplo n.º 5
0
        public void DoesNotMatchXproj()
        {
            using (var files = new TemporaryFileProvider())
            {
                var finder = new MsBuildProjectFinder(files.Root);
                files.Add("test.xproj", "");

                Assert.Throws <FileNotFoundException>(() => finder.FindMsBuildProject(null));
            }
        }
Exemplo n.º 6
0
        public void ThrowsWhenMultipleFile()
        {
            using (var files = new TemporaryFileProvider())
            {
                files.Add("Test1.csproj", "");
                files.Add("Test2.csproj", "");
                var finder = new MsBuildProjectFinder(files.Root);

                Assert.Throws <FileNotFoundException>(() => finder.FindMsBuildProject(null));
            }
        }
Exemplo n.º 7
0
        public void FindsSingleProject(string extension)
        {
            using (var files = new TemporaryFileProvider())
            {
                var filename = "TestProject" + extension;
                files.Add(filename, "");

                var finder = new MsBuildProjectFinder(files.Root);

                Assert.Equal(Path.Combine(files.Root, filename), finder.FindMsBuildProject(null));
            }
        }
Exemplo n.º 8
0
        private async Task <int> ListFilesAsync(
            IReporter reporter,
            string project,
            CancellationToken cancellationToken)
        {
            // TODO multiple projects should be easy enough to add here
            string projectFile;

            try
            {
                projectFile = MsBuildProjectFinder.FindMsBuildProject(_workingDirectory, project);
            }
            catch (FileNotFoundException ex)
            {
                reporter.Error(ex.Message);
                return(1);
            }

            var fileSetFactory = new MsBuildFileSetFactory(reporter,
                                                           DotNetWatchOptions.Default,
                                                           projectFile,
                                                           waitOnError: false,
                                                           trace: false);
            var files = await fileSetFactory.CreateAsync(cancellationToken);

            if (files == null)
            {
                return(1);
            }

            foreach (var group in files.GroupBy(g => g.FileKind).OrderBy(g => g.Key))
            {
                if (group.Key == FileKind.StaticFile)
                {
                    _console.Out.WriteLine("::: Watch Action: Refresh browser :::");
                }

                foreach (var file in group)
                {
                    if (file.FileKind == FileKind.StaticFile)
                    {
                        _console.Out.WriteLine($"{file.FilePath} ~/{file.StaticWebAssetPath}");
                    }
                    else
                    {
                        _console.Out.WriteLine(file.FilePath);
                    }
                }
            }

            return(0);
        }
Exemplo n.º 9
0
        private async Task <int> MainInternalAsync(
            IReporter reporter,
            string project,
            IReadOnlyCollection <string> args,
            CancellationToken cancellationToken)
        {
            // TODO multiple projects should be easy enough to add here
            string projectFile;

            try
            {
                projectFile = MsBuildProjectFinder.FindMsBuildProject(_workingDirectory, project);
            }
            catch (FileNotFoundException ex)
            {
                reporter.Error(ex.Message);
                return(1);
            }

            var watchOptions = DotNetWatchOptions.Default;

            var fileSetFactory = new MsBuildFileSetFactory(reporter,
                                                           watchOptions,
                                                           projectFile,
                                                           waitOnError: true,
                                                           trace: false);
            var processInfo = new ProcessSpec
            {
                Executable           = new Muxer().MuxerPath,
                WorkingDirectory     = Path.GetDirectoryName(projectFile),
                Arguments            = args,
                EnvironmentVariables =
                {
                    ["DOTNET_WATCH"] = "1"
                },
            };

            if (CommandLineOptions.IsPollingEnabled)
            {
                _reporter.Output("Polling file watcher is enabled");
            }

            await using var watcher = new DotNetWatcher(reporter, fileSetFactory, watchOptions);
            await watcher.WatchAsync(processInfo, cancellationToken);

            return(0);
        }
Exemplo n.º 10
0
        private async Task <int> ListFilesAsync(
            IReporter reporter,
            string project,
            CancellationToken cancellationToken)
        {
            // TODO multiple projects should be easy enough to add here
            string projectFile;

            try
            {
                projectFile = MsBuildProjectFinder.FindMsBuildProject(_workingDirectory, project);
            }
            catch (FileNotFoundException ex)
            {
                reporter.Error(ex.Message);
                return(1);
            }

            var fileSetFactory = new MsBuildFileSetFactory(
                reporter,
                DotNetWatchOptions.Default,
                projectFile,
                waitOnError: false,
                trace: false);
            var files = await fileSetFactory.CreateAsync(cancellationToken);

            if (files == null)
            {
                return(1);
            }

            foreach (var file in files)
            {
                _console.Out.WriteLine(file.FilePath);
            }

            return(0);
        }
Exemplo n.º 11
0
        private async Task <int> MainInternalAsync(
            IReporter reporter,
            string project,
            IReadOnlyList <string> args,
            CancellationToken cancellationToken)
        {
            // TODO multiple projects should be easy enough to add here
            string projectFile;

            try
            {
                projectFile = MsBuildProjectFinder.FindMsBuildProject(_workingDirectory, project);
            }
            catch (FileNotFoundException ex)
            {
                reporter.Error(ex.Message);
                return(1);
            }

            var isDefaultRunCommand = false;

            if (args.Count == 1 && args[0] == "run")
            {
                isDefaultRunCommand = true;
            }
            else if (args.Count == 0)
            {
                isDefaultRunCommand = true;
                args = new[] { "run" };
            }

            var watchOptions = DotNetWatchOptions.Default;

            var fileSetFactory = new MsBuildFileSetFactory(reporter,
                                                           watchOptions,
                                                           projectFile,
                                                           waitOnError: true,
                                                           trace: false);
            var processInfo = new ProcessSpec
            {
                Executable           = DotnetMuxer.MuxerPath,
                WorkingDirectory     = Path.GetDirectoryName(projectFile),
                Arguments            = args,
                EnvironmentVariables =
                {
                    ["DOTNET_WATCH"] = "1"
                },
            };

            if (CommandLineOptions.IsPollingEnabled)
            {
                _reporter.Output("Polling file watcher is enabled");
            }

            var defaultProfile = LaunchSettingsProfile.ReadDefaultProfile(_workingDirectory, reporter);

            var context = new DotNetWatchContext
            {
                ProcessSpec = processInfo,
                Reporter    = _reporter,
                SuppressMSBuildIncrementalism = watchOptions.SuppressMSBuildIncrementalism,
                DefaultLaunchSettingsProfile  = defaultProfile,
            };

            if (isDefaultRunCommand && !string.IsNullOrEmpty(defaultProfile?.HotReloadProfile))
            {
                _reporter.Verbose($"Found HotReloadProfile={defaultProfile.HotReloadProfile}. Watching with hot-reload");

                // We'll sue hot-reload based watching if
                // a) watch was invoked with no args or with exactly one arg - the run command e.g. `dotnet watch` or `dotnet watch run`
                // b) The launch profile supports hot-reload based watching.
                // The watcher will complain if users configure this for runtimes that would not support it.
                await using var watcher = new HotReloadDotNetWatcher(reporter, fileSetFactory, watchOptions, _console);
                await watcher.WatchAsync(context, cancellationToken);
            }
            else
            {
                _reporter.Verbose("Did not find a HotReloadProfile or running a non-default command. Watching with legacy behavior.");

                // We'll use the presence of a profile to decide if we're going to use the hot-reload based watching.
                // The watcher will complain if users configure this for runtimes that would not support it.
                await using var watcher = new DotNetWatcher(reporter, fileSetFactory, watchOptions);
                await watcher.WatchAsync(context, cancellationToken);
            }

            return(0);
        }
Exemplo n.º 12
0
    public string Resolve(string project, string configuration)
    {
        var    finder = new MsBuildProjectFinder(_workingDirectory);
        string projectFile;

        try
        {
            projectFile = finder.FindMsBuildProject(project);
        }
        catch (Exception ex)
        {
            _reporter.Error(ex.Message);
            return(null);
        }

        _reporter.Verbose(SecretsHelpersResources.FormatMessage_Project_File_Path(projectFile));

        configuration = !string.IsNullOrEmpty(configuration)
            ? configuration
            : DefaultConfig;

        var outputFile = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());

        try
        {
            var psi = new ProcessStartInfo
            {
                FileName = DotNetMuxer.MuxerPathOrDefault(),
                RedirectStandardOutput = true,
                RedirectStandardError  = true,
                UseShellExecute        = false,
                ArgumentList           =
                {
                    "msbuild",
                    projectFile,
                    "/nologo",
                    "/t:_ExtractUserSecretsMetadata",     // defined in SecretManager.targets
                    "/p:_UserSecretsMetadataFile=" + outputFile,
                    "/p:Configuration=" + configuration,
                    "/p:CustomAfterMicrosoftCommonTargets=" + _targetsFile,
                    "/p:CustomAfterMicrosoftCommonCrossTargetingTargets=" + _targetsFile,
                    "-verbosity:detailed",
                }
            };

#if DEBUG
            _reporter.Verbose($"Invoking '{psi.FileName} {psi.Arguments}'");
#endif

            using var process = new Process()
                  {
                      StartInfo = psi,
                  };

            var outputBuilder = new StringBuilder();
            var errorBuilder  = new StringBuilder();
            process.OutputDataReceived += (_, d) =>
            {
                if (!string.IsNullOrEmpty(d.Data))
                {
                    outputBuilder.AppendLine(d.Data);
                }
            };
            process.ErrorDataReceived += (_, d) =>
            {
                if (!string.IsNullOrEmpty(d.Data))
                {
                    errorBuilder.AppendLine(d.Data);
                }
            };
            process.Start();
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();
            process.WaitForExit();

            if (process.ExitCode != 0)
            {
                _reporter.Verbose(outputBuilder.ToString());
                _reporter.Verbose(errorBuilder.ToString());
                _reporter.Error($"Exit code: {process.ExitCode}");
                _reporter.Error(SecretsHelpersResources.FormatError_ProjectFailedToLoad(projectFile));
                return(null);
            }

            if (!File.Exists(outputFile))
            {
                _reporter.Error(SecretsHelpersResources.FormatError_ProjectMissingId(projectFile));
                return(null);
            }

            var id = File.ReadAllText(outputFile)?.Trim();
            if (string.IsNullOrEmpty(id))
            {
                _reporter.Error(SecretsHelpersResources.FormatError_ProjectMissingId(projectFile));
            }
            return(id);
        }
        finally
        {
            TryDelete(outputFile);
        }
    }
Exemplo n.º 13
0
    private static string ResolveProjectPath(string name, string path)
    {
        var finder = new MsBuildProjectFinder(path);

        return(finder.FindMsBuildProject(name));
    }
Exemplo n.º 14
0
        private async Task <int> MainInternalAsync(CommandLineOptions options, CancellationToken cancellationToken)
        {
            // TODO multiple projects should be easy enough to add here
            string projectFile;

            try
            {
                projectFile = MsBuildProjectFinder.FindMsBuildProject(_workingDirectory, options.Project);
            }
            catch (FileNotFoundException ex)
            {
                _reporter.Error(ex.Message);
                return(1);
            }

            var args = options.RemainingArguments;

            var isDefaultRunCommand = false;

            if (args.Count == 1 && args[0] == "run")
            {
                isDefaultRunCommand = true;
            }
            else if (args.Count == 0)
            {
                isDefaultRunCommand = true;
                args = new[] { "run" };
            }

            var watchOptions = DotNetWatchOptions.Default;

            watchOptions.NonInteractive = options.NonInteractive;

            var fileSetFactory = new MsBuildFileSetFactory(_reporter,
                                                           watchOptions,
                                                           projectFile,
                                                           waitOnError: true,
                                                           trace: false);
            var processInfo = new ProcessSpec
            {
                Executable           = DotnetMuxer.MuxerPath,
                WorkingDirectory     = Path.GetDirectoryName(projectFile),
                Arguments            = args,
                EnvironmentVariables =
                {
                    ["DOTNET_WATCH"] = "1"
                },
            };

            if (CommandLineOptions.IsPollingEnabled)
            {
                _reporter.Output("Polling file watcher is enabled");
            }

            var defaultProfile = LaunchSettingsProfile.ReadDefaultProfile(processInfo.WorkingDirectory, _reporter) ?? new();

            var context = new DotNetWatchContext
            {
                ProcessSpec = processInfo,
                Reporter    = _reporter,
                SuppressMSBuildIncrementalism = watchOptions.SuppressMSBuildIncrementalism,
                DefaultLaunchSettingsProfile  = defaultProfile,
            };

            context.ProjectGraph = TryReadProject(projectFile);

            if (!options.NoHotReload && isDefaultRunCommand && context.ProjectGraph is not null && IsHotReloadSupported(context.ProjectGraph))
            {
                _reporter.Verbose($"Project supports hot reload and was configured to run with the default run-command. Watching with hot-reload");

                // Use hot-reload based watching if
                // a) watch was invoked with no args or with exactly one arg - the run command e.g. `dotnet watch` or `dotnet watch run`
                // b) The launch profile supports hot-reload based watching.
                // The watcher will complain if users configure this for runtimes that would not support it.
                await using var watcher = new HotReloadDotNetWatcher(_reporter, _requester, fileSetFactory, watchOptions, _console, _workingDirectory);
                await watcher.WatchAsync(context, cancellationToken);
            }
Exemplo n.º 15
0
        private async Task <int> RunCoreAsync(CommandLineOptions options)
        {
            string projectFilePath;

            try { projectFilePath = MsBuildProjectFinder.FindMsBuildProject(_workingDir, options.Project); }
            catch (FileNotFoundException ex)
            {
                _reporter.Error(ex.Message);
                return(1);
            }

            var projectDirPath = Path.GetDirectoryName(projectFilePath);

            string configFilePath;

            if (options.ConfigSources.HasFlag(ConfigSources.ConfigFile))
            {
                configFilePath = options.ConfigFile ?? GetDefaultConfigFilePath(projectDirPath);
            }
            else
            {
                configFilePath = null;
            }

            string compilationBasePath;
            IEnumerable <string> assemblyFilePaths;

            if (options.ConfigSources.HasFlag(ConfigSources.AppAssembly) || options.ConfigSources.HasFlag(ConfigSources.OutputAssemblies))
            {
                var targetFilePath = options.BuildTargetPath;
                if (targetFilePath == null)
                {
                    _reporter.Output($"Building project {projectFilePath}...");

                    targetFilePath = await new MsBuildEnsureBuildTarget(_reporter, projectFilePath).ExecuteAsync(options.BuildConfiguration, _cts.Token);

                    // we need the project to be built if configuration is specified by code
                    if (targetFilePath == null)
                    {
                        return(1);
                    }
                }

                compilationBasePath = Path.GetDirectoryName(targetFilePath);

                if (options.ConfigSources.HasFlag(ConfigSources.OutputAssemblies))
                {
                    assemblyFilePaths = Directory.EnumerateFiles(compilationBasePath, "*.dll", SearchOption.TopDirectoryOnly);
                }
                else
                {
                    assemblyFilePaths = Enumerable.Empty <string>();
                }

                if (options.ConfigSources.HasFlag(ConfigSources.AppAssembly))
                {
                    assemblyFilePaths = assemblyFilePaths.Prepend(targetFilePath);
                }

                assemblyFilePaths = assemblyFilePaths.Distinct();
            }
            else
            {
                if (options.BuildTargetPath == null)
                {
                    // TODO: prefer release build?
                    compilationBasePath = Directory.EnumerateFiles(projectDirPath, BundleBuilderProxy.BundlingAssemblyName + ".dll", SearchOption.AllDirectories).FirstOrDefault();
                    if (compilationBasePath != null)
                    {
                        compilationBasePath = Path.GetDirectoryName(compilationBasePath);
                    }
                }
                else
                {
                    compilationBasePath = Path.GetDirectoryName(options.BuildTargetPath);
                }

                assemblyFilePaths = Enumerable.Empty <string>();
            }

            // we load the application into a separate AssemblyLoadContext (to avoid assembly version mismatches),
            // then we pass the discovered bundling configurations to the design-time bundle builder implementation residing in the main assembly

            var assemblyLoader = new AssemblyLoader(compilationBasePath);

            var bundleBuilderProxy = new BundleBuilderProxy(assemblyLoader, _reporter);

            var settings = new Dictionary <string, object>(StringComparer.OrdinalIgnoreCase)
            {
                ["ProjectFilePath"]     = projectFilePath,
                ["CompilationBasePath"] = compilationBasePath,
                ["Mode"]   = options.Mode.ToString(),
                ["Logger"] = new Action <int, string>(Log)
            };

            if (configFilePath != null)
            {
                settings["ConfigFilePath"] = configFilePath;
            }

            await bundleBuilderProxy.ProcessConfigurationsAsync(assemblyFilePaths, settings, _cts.Token);

            return(0);
        }