public override async Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel, Solution solution)
        {
            if (solution == null)
            {
                return;
            }

            if (!(viewModel is SolutionUpdateViewModel updateViewModel))
            {
                throw new ArgumentException($"Argument {nameof(viewModel)} must be of type {nameof(SolutionUpdateViewModel)}");
            }

            await _licenseHeaderExtension.JoinableTaskFactory.SwitchToMainThreadAsync();

            var allSolutionProjectsSearcher = new AllSolutionProjectsSearcher();
            var projectsInSolution          = allSolutionProjectsSearcher.GetAllProjects(solution);

            updateViewModel.ProcessedProjectCount = 0;
            updateViewModel.ProjectCount          = projectsInSolution.Count;
            var removeAllLicenseHeadersCommand = new RemoveLicenseHeaderFromAllFilesInProjectHelper(cancellationToken, _licenseHeaderExtension, updateViewModel);

            foreach (var project in projectsInSolution)
            {
                await removeAllLicenseHeadersCommand.ExecuteAsync(project);
                await IncrementProjectCountAsync(updateViewModel).ConfigureAwait(true);
            }
        }
Example #2
0
 public AddLicenseHeaderToAllFilesInProjectHelper(
     CancellationToken cancellationToken,
     ILicenseHeaderExtension licenseHeaderExtension,
     BaseUpdateViewModel baseUpdateViewModel)
 {
     _cancellationToken      = cancellationToken;
     _licenseHeaderExtension = licenseHeaderExtension;
     _baseUpdateViewModel    = baseUpdateViewModel;
 }
Example #3
0
 /// <summary>
 ///   Creates a replacer progress that represents the progress of updated files in folders and projects.
 /// </summary>
 /// <param name="viewModel">
 ///   Specifies the view model that contains the progress bar whose update progress should be
 ///   visualized.
 /// </param>
 /// <param name="projectName">Specifies the name of the project that is updated.</param>
 /// <param name="fileOpenedStatus">Specifies what files are currently open in the current project.</param>
 /// <param name="cancellationToken">
 ///   Specifies the cancellation token that indicates if the current updating progress has
 ///   been cancelled by the user.
 /// </param>
 public static IProgress <ReplacerProgressContentReport> CreateProgress(
     BaseUpdateViewModel viewModel,
     string projectName,
     IDictionary <string, bool> fileOpenedStatus,
     CancellationToken cancellationToken)
 {
     return(new ReplacerProgress <ReplacerProgressContentReport> (
                report => OnProgressReportedAsync(report, viewModel, projectName, fileOpenedStatus, cancellationToken).FireAndForget()));
 }
Example #4
0
        /// <summary>
        ///   Processes a range of <see cref="ReplacerResult{TSuccess,TError}" /> objects, including possible error handling.
        /// </summary>
        /// <param name="result">Specifies the replacer result. Indicates whether the specific operation succeeded or failed.</param>
        /// <param name="licenseHeaderExtension">
        ///   A <see cref="ILicenseHeaderExtension" /> instance used to access members exposed
        ///   by the LHM Extension Package.
        /// </param>
        /// <param name="viewModel">
        ///   A <see cref="BaseUpdateViewModel" /> instance used to update progress indicator properties if a
        ///   <see cref="LicenseHeaderReplacer" /> newly needs to be invoked.
        /// </param>
        /// <param name="projectName">
        ///   The name of the project the files updated by a <see cref="LicenseHeaderReplacer" /> operation
        ///   belong to.
        /// </param>
        /// <param name="fileOpenedStatus">
        ///   Provides information on which files (full path, dictionary key) are currently opened
        ///   (values).
        /// </param>
        /// <param name="cancellationToken">
        ///   A <see cref="CancellationToken" /> that can be used to cancel pending Core operations
        ///   if they have not been started yet.
        /// </param>
        public static async Task HandleResultAsync(
            IEnumerable <ReplacerResult <ReplacerSuccess, ReplacerError <LicenseHeaderContentInput> > > result,
            ILicenseHeaderExtension licenseHeaderExtension,
            BaseUpdateViewModel viewModel,
            string projectName,
            IDictionary <string, bool> fileOpenedStatus,
            CancellationToken cancellationToken)
        {
            // collect NonCommentText-errors and ask if license header should still be inserted
            var errors = result.Where(replacerResult => !replacerResult.IsSuccess).Select(replacerResult => replacerResult.Error).ToList();

            var nonCommentTextErrorsByExtension = errors.Where(x => x.Type == ReplacerErrorType.NonCommentText).GroupBy(x => Path.GetExtension(x.Input.DocumentPath));

            var inputIgnoringNonCommentText = new List <LicenseHeaderContentInput>();

            foreach (var extension in nonCommentTextErrorsByExtension)
            {
                var message = string.Format(Resources.Warning_InvalidLicenseHeader, extension.Key).ReplaceNewLines();
                if (!MessageBoxHelper.AskYesNo(message, Resources.Warning, true))
                {
                    continue;
                }

                foreach (var failedFile in extension)
                {
                    failedFile.Input.IgnoreNonCommentText = true;
                    inputIgnoringNonCommentText.Add(failedFile.Input);
                }
            }

            // collect other errors and the ones that occurred while "force-inserting" headers with non-comment-text
            var overallErrors = errors.Where(x => x.Type != ReplacerErrorType.NonCommentText && x.Type != ReplacerErrorType.LicenseHeaderDocument).ToList();

            if (inputIgnoringNonCommentText.Count > 0)
            {
                viewModel.FileCountCurrentProject = inputIgnoringNonCommentText.Count;
                var resultIgnoringNonCommentText = await licenseHeaderExtension.LicenseHeaderReplacer.RemoveOrReplaceHeader(
                    inputIgnoringNonCommentText,
                    CreateProgress (viewModel, projectName, fileOpenedStatus, cancellationToken),
                    cancellationToken);

                overallErrors.AddRange(resultIgnoringNonCommentText.Where(replacerResult => !replacerResult.IsSuccess).Select(replacerResult => replacerResult.Error));
            }

            // display all errors collected from "first attempt" and "force-insertion"
            if (overallErrors.Count == 0)
            {
                return;
            }

            MessageBoxHelper.ShowError($"{overallErrors.Count} unexpected errors have occurred. See output window or log file for more details");
            foreach (var otherError in overallErrors)
            {
                s_log.Error($"File '{otherError.Input.DocumentPath}' failed: {otherError.Description}");
            }
        }
Example #5
0
        public override async Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel)
        {
            await _licenseHeaderExtension.JoinableTaskFactory.SwitchToMainThreadAsync();

            var obj = _licenseHeaderExtension.GetSolutionExplorerItem();
            var removeAllLicenseHeadersCommand =
                new RemoveLicenseHeaderFromAllFilesInProjectHelper(cancellationToken, _licenseHeaderExtension, viewModel);

            await removeAllLicenseHeadersCommand.ExecuteAsync(obj);
        }
        private static async Task HandleAddLicenseHeaderToAllFilesInProjectResultAsync(
            CancellationToken cancellationToken,
            ILicenseHeaderExtension serviceProvider,
            object obj,
            AddLicenseHeaderToAllFilesResult addResult,
            BaseUpdateViewModel baseUpdateViewModel)
        {
            await serviceProvider.JoinableTaskFactory.SwitchToMainThreadAsync();

            var project     = obj as Project;
            var projectItem = obj as ProjectItem;

            if (project == null && projectItem == null)
            {
                return;
            }
            var currentProject = project;

            if (projectItem != null)
            {
                currentProject = projectItem.ContainingProject;
            }

            if (addResult.NoHeaderFound)
            {
                // No license header found...
                var solutionSearcher = new AllSolutionProjectsSearcher();
                var projects         = solutionSearcher.GetAllProjects(serviceProvider.Dte2.Solution);

                if (projects.Any(projectInSolution => LicenseHeaderFinder.GetHeaderDefinitionForProjectWithoutFallback(projectInSolution) != null))
                {
                    baseUpdateViewModel.ProcessedFilesCountCurrentProject = 0;
                    // If another project has a license header, offer to add a link to the existing one.
                    if (MessageBoxHelper.AskYesNo(Resources.Question_AddExistingDefinitionFileToProject.ReplaceNewLines()))
                    {
                        ExistingLicenseHeaderDefinitionFileAdder.AddDefinitionFileToOneProject(currentProject.FileName, currentProject.ProjectItems);
                        await AddLicenseHeaderToAllFilesAsync(cancellationToken, serviceProvider, baseUpdateViewModel);
                    }
                }
                else
                {
                    // If no project has a license header, offer to add one for the solution.
                    if (MessageBoxHelper.AskYesNo(Resources.Question_AddNewLicenseHeaderDefinitionForSolution.ReplaceNewLines()))
                    {
                        AddNewSolutionLicenseHeaderDefinitionFileCommand.Instance.Invoke(serviceProvider.Dte2.Solution);
                    }
                }
            }
        }
        public static async Task AddLicenseHeaderToAllFilesAsync(
            CancellationToken cancellationToken,
            ILicenseHeaderExtension serviceProvider,
            BaseUpdateViewModel folderProjectUpdateViewModel)
        {
            await serviceProvider.JoinableTaskFactory.SwitchToMainThreadAsync();

            var obj = serviceProvider.GetSolutionExplorerItem();
            var addLicenseHeaderToAllFilesCommand = new AddLicenseHeaderToAllFilesInProjectHelper(
                cancellationToken,
                serviceProvider,
                folderProjectUpdateViewModel);

            var addLicenseHeaderToAllFilesResult = await addLicenseHeaderToAllFilesCommand.RemoveOrReplaceHeadersAsync(obj);

            await HandleLinkedFilesAndShowMessageBoxAsync(serviceProvider, addLicenseHeaderToAllFilesResult.LinkedItems);
            await HandleAddLicenseHeaderToAllFilesInProjectResultAsync(
                cancellationToken,
                serviceProvider,
                obj,
                addLicenseHeaderToAllFilesResult,
                folderProjectUpdateViewModel);
        }
Example #8
0
        private static async Task OnProgressReportedAsync(
            ReplacerProgressContentReport progress,
            BaseUpdateViewModel baseUpdateViewModel,
            string projectName,
            IDictionary <string, bool> fileOpenedStatus,
            CancellationToken cancellationToken)
        {
            await LicenseHeadersPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (!cancellationToken.IsCancellationRequested)
            {
                var result = new ReplacerResult <ReplacerSuccess, ReplacerError <LicenseHeaderContentInput> > (
                    new ReplacerSuccess(progress.ProcessedFilePath, progress.ProcessFileNewContent));
                if (fileOpenedStatus.TryGetValue(progress.ProcessedFilePath, out var wasOpen))
                {
                    await HandleResultAsync(result, LicenseHeadersPackage.Instance, wasOpen, false);
                }
                else
                {
                    await HandleResultAsync(result, LicenseHeadersPackage.Instance, false, false);
                }
            }

            if (baseUpdateViewModel == null)
            {
                return;
            }

            baseUpdateViewModel.FileCountCurrentProject           = progress.TotalFileCount;
            baseUpdateViewModel.ProcessedFilesCountCurrentProject = progress.ProcessedFileCount;

            if (baseUpdateViewModel is SolutionUpdateViewModel solutionUpdateViewModel)
            {
                solutionUpdateViewModel.CurrentProject = projectName;
            }
        }
 public override async Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel)
 {
     await FolderProjectMenuHelper.AddLicenseHeaderToAllFilesAsync(cancellationToken, _licenseHeaderExtension, viewModel);
 }
 public override Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel, Solution solution)
 {
     return(DoWorkAsync(cancellationToken, viewModel));
 }
Example #11
0
 /// <summary>
 ///   Carries out the work that the corresponding <see cref="IMenuItemButtonHandler" />
 ///   instance wants to delegate to this <see cref="MenuItemButtonHandlerImplementation" /> instance.
 /// </summary>
 /// <param name="cancellationToken">The token to monitor for cancellation requests</param>
 /// <param name="viewModel">
 ///   The view model this implementation needs to update in order to reflect process in the corresponding
 ///   dialog window.
 /// </param>
 public abstract Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel);
Example #12
0
 /// <summary>
 ///   Carries out the work that the corresponding <see cref="IMenuItemButtonHandler" /> instance wants to delegate to this
 ///   <see cref="MenuItemButtonHandlerImplementation" /> instance.
 /// </summary>
 /// <param name="cancellationToken">The token to monitor for cancellation requests</param>
 /// <param name="viewModel">
 ///   The view model this implementation needs to update in order to reflect process in the corresponding
 ///   dialog window.
 /// </param>
 /// <param name="solution">The <see cref="Solution" /> instance the work to be done is related with.</param>
 /// <param name="window">
 ///   The <see cref="System.Windows.Window" /> that is on top of the screen while the work to be done is
 ///   being carried out.
 /// </param>
 /// <remarks>
 ///   If not both a Solution and a Window are strictly required for the desired work to be done (even though one or both of
 ///   them might even be
 ///   present, i. e. could theoretically be supplied), use another overload, if possible. If this is not possible, a
 ///   suitable
 ///   overload that does not expect the superfluous parameters is called by the actual implementation.
 /// </remarks>
 public abstract Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel, Solution solution, Window window);
Example #13
0
        private async Task HandleButtonInternalAsync(object solutionObject, MenuItemButtonHandlerImplementation handler, BaseUpdateViewModel solutionUpdateViewModel)
        {
            await LicenseHeadersPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();

            if (!(solutionObject is Solution solution))
            {
                return;
            }

            _cancellationTokenSource = new CancellationTokenSource();
            try
            {
                await handler.DoWorkAsync(_cancellationTokenSource.Token, solutionUpdateViewModel, solution, _dialog);
            }
            catch (OperationCanceledException)
            {
                await LicenseHeadersPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();

                _dialog.Close();
            }
            catch (Exception ex)
            {
                MessageBoxHelper.ShowMessage(
                    $"The operation '{handler.Description}' failed with the exception '{ex.Message}'. See Visual Studio Output Window for Details.");
                s_log.Error($"The operation '{handler.Description}' failed.", ex);
            }

            await LicenseHeadersPackage.Instance.JoinableTaskFactory.SwitchToMainThreadAsync();

            _dialog.Close();
        }
        private async Task IncrementProjectCountAsync(BaseUpdateViewModel viewModel)
        {
            await _licenseHeaderExtension.JoinableTaskFactory.SwitchToMainThreadAsync();

            viewModel.ProcessedProjectCount++;
        }
 public override Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel)
 {
     throw new NotSupportedException(UnsupportedOverload);
 }
Example #16
0
        public override async Task DoWorkAsync(CancellationToken cancellationToken, BaseUpdateViewModel viewModel, Solution solution, Window window)
        {
            if (solution == null)
            {
                return;
            }

            if (!(viewModel is SolutionUpdateViewModel updateViewModel))
            {
                throw new ArgumentException($"Argument {nameof(viewModel)} must be of type {nameof(SolutionUpdateViewModel)}");
            }

            await _licenseHeaderExtension.JoinableTaskFactory.SwitchToMainThreadAsync();

            var solutionHeaderDefinitions = LicenseHeaderFinder.GetHeaderDefinitionForSolution(solution);

            var allSolutionProjectsSearcher = new AllSolutionProjectsSearcher();
            var projectsInSolution          = allSolutionProjectsSearcher.GetAllProjects(solution);

            var projectsWithoutLicenseHeaderFile = projectsInSolution
                                                   .Where(project => LicenseHeaderFinder.GetHeaderDefinitionForProjectWithoutFallback(project) == null)
                                                   .ToList();

            var projectsWithLicenseHeaderFile = projectsInSolution
                                                .Where(project => LicenseHeaderFinder.GetHeaderDefinitionForProjectWithoutFallback(project) != null)
                                                .ToList();

            if (solutionHeaderDefinitions != null || !projectsWithoutLicenseHeaderFile.Any())
            {
                // Every project is covered either by a solution or project level license header definition, go ahead and add them.
                await AddLicenseHeaderToProjectsAsync(cancellationToken, projectsInSolution, updateViewModel);
            }
            else
            {
                // Some projects are not covered by a header.

                var someProjectsHaveDefinition = projectsWithLicenseHeaderFile.Count > 0;
                if (someProjectsHaveDefinition)
                {
                    // Some projects have a header. Ask the user if they want to add an existing header to the uncovered projects.
                    if (await DefinitionFilesShouldBeAddedAsync(projectsWithoutLicenseHeaderFile, window))
                    {
                        ExistingLicenseHeaderDefinitionFileAdder.AddDefinitionFileToMultipleProjects(projectsWithoutLicenseHeaderFile);
                    }

                    await AddLicenseHeaderToProjectsAsync(cancellationToken, projectsInSolution, updateViewModel);
                }
                else
                {
                    // No projects have definition. Ask the user if they want to add a solution level header definition.
                    if (await MessageBoxHelper.AskYesNoAsync(window, Resources.Question_AddNewLicenseHeaderDefinitionForSolution.ReplaceNewLines()).ConfigureAwait(true))
                    {
                        AddNewSolutionLicenseHeaderDefinitionFileCommand.Instance.Invoke(solution);

                        // They want to go ahead and apply without editing.
                        if (!await MessageBoxHelper.AskYesNoAsync(window, Resources.Question_StopForConfiguringDefinitionFilesSingleFile).ConfigureAwait(true))
                        {
                            await AddLicenseHeaderToProjectsAsync(cancellationToken, projectsInSolution, updateViewModel);
                        }
                    }
                }
            }
        }