public void VsTextViewCreated(IVsTextView textViewAdapter)
        {
            IWpfTextView textView = EditorAdaptersFactoryService.GetWpfTextView(textViewAdapter);

            if (!DocumentService.TryGetTextDocument(textView.TextBuffer, out ITextDocument doc))
            {
                return;
            }

            string fileName = Path.GetFileName(doc.FilePath);

            if (!fileName.Equals(Constants.ConfigFileName, StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            new CompletionController(textViewAdapter, textView, CompletionBroker);


            _dependencies = Dependencies.FromConfigFile(doc.FilePath);
            _manifest     = Manifest.FromFileAsync(doc.FilePath, _dependencies, CancellationToken.None).Result;
            _manifestPath = doc.FilePath;
            _project      = VsHelpers.GetDTEProjectFromConfig(_manifestPath);

            if (_manifest == null)
            {
                AddErrorToList(PredefinedErrors.ManifestMalformed());
            }

            doc.FileActionOccurred += OnFileSaved;
            textView.Closed        += OnViewClosed;
        }
 public void Predefined()
 {
     TestError(PredefinedErrors.UnknownException(), "LIB000");
     TestError(PredefinedErrors.ProviderUnknown("_prov_"), "LIB001", "_prov_");
     TestError(PredefinedErrors.UnableToResolveSource("_libid_", "_prov_"), "LIB002", "_libid_", "_prov_");
     TestError(PredefinedErrors.CouldNotWriteFile("file.js"), "LIB003", "file.js");
     TestError(PredefinedErrors.ManifestMalformed(), "LIB004");
 }
        private async Task UninstallLibraryAsync(string configFilePath, string libraryName, string version, string providerId, CancellationToken cancellationToken)
        {
            string libraryId = LibraryIdToNameAndVersionConverter.Instance.GetLibraryId(libraryName, version, providerId);

            Logger.LogEventsHeader(OperationType.Uninstall, libraryId);

            try
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                var      dependencies = _dependenciesFactory.FromConfigFile(configFilePath);
                Manifest manifest     = await Manifest.FromFileAsync(configFilePath, dependencies, cancellationToken).ConfigureAwait(false);

                ILibraryOperationResult result = null;

                if (manifest == null)
                {
                    result = LibraryOperationResult.FromError(PredefinedErrors.ManifestMalformed());
                }
                else
                {
                    IHostInteraction hostInteraction = dependencies.GetHostInteractions();
                    result = await manifest.UninstallAsync(libraryName, version, async (filesPaths) => await hostInteraction.DeleteFilesAsync(filesPaths, cancellationToken), cancellationToken).ConfigureAwait(false);
                }

                sw.Stop();

                if (result.Errors.Any())
                {
                    Logger.LogErrorsSummary(new List <ILibraryOperationResult> {
                        result
                    }, OperationType.Uninstall);
                }
                else
                {
                    Logger.LogEventsSummary(new List <ILibraryOperationResult> {
                        result
                    }, OperationType.Uninstall, sw.Elapsed);
                }

                Telemetry.LogEventsSummary(new List <ILibraryOperationResult> {
                    result
                }, OperationType.Uninstall, sw.Elapsed);
            }
            catch (OperationCanceledException ex)
            {
                Logger.LogEvent(string.Format(LibraryManager.Resources.Text.Uninstall_LibraryCancelled, libraryId), LogLevel.Task);
                Telemetry.TrackException($@"{OperationType.Uninstall}Cancelled", ex);
            }
        }
Exemple #4
0
#pragma warning restore CA1819 // Properties should not return arrays

        public override bool Execute()
        {
            Logger.Instance.Clear();
            var configFilePath = new FileInfo(Path.Combine(ProjectDirectory, FileName));

            if (!configFilePath.Exists)
            {
                Log.LogWarning(configFilePath.Name + " does not exist");
                return(true);
            }

            var sw = new Stopwatch();

            sw.Start();

            CancellationToken token = CancellationToken.None;

            Log.LogMessage(MessageImportance.High, Environment.NewLine + Resources.Text.Restore_OperationStarted);

            var      dependencies = Dependencies.FromTask(ProjectDirectory, ProviderAssemblies.Select(pa => new FileInfo(pa.ItemSpec).FullName));
            Manifest manifest     = Manifest.FromFileAsync(configFilePath.FullName, dependencies, token).Result;
            var      logger       = dependencies.GetHostInteractions().Logger as Logger;

            if (manifest == null)
            {
                sw.Stop();
                LogErrors(new[] { PredefinedErrors.ManifestMalformed() });
                FlushLogger(logger);

                return(false);
            }

            IEnumerable <ILibraryOperationResult> validationResults = manifest.GetValidationResultsAsync(token).Result;

            if (!validationResults.All(r => r.Success))
            {
                sw.Stop();
                LogErrors(validationResults.SelectMany(r => r.Errors));

                return(false);
            }

            IEnumerable <ILibraryOperationResult> results = manifest.RestoreAsync(token).Result;

            sw.Stop();
            FlushLogger(logger);
            PopulateFilesWritten(results, dependencies.GetHostInteractions());
            LogResults(sw, results);

            return(!Log.HasLoggedErrors);
        }
        protected async Task <Manifest> GetManifestAsync()
        {
            if (!File.Exists(Settings.ManifestFileName))
            {
                throw new InvalidOperationException(string.Format(Resources.Text.LibmanJsonNotFound, Settings.ManifestFileName));
            }

            Manifest manifest = await Manifest.FromFileAsync(Settings.ManifestFileName, ManifestDependencies, CancellationToken.None);

            if (manifest == null)
            {
                Logger.Log(PredefinedErrors.ManifestMalformed().Message, LogLevel.Error);
                throw new InvalidOperationException(Resources.Text.FixManifestFile);
            }

            return(manifest);
        }
        public void Constructor()
        {
            Mocks.LibraryInstallationState state = GetState();

            var ctor1 = new LibraryInstallationResult(state);

            Assert.AreEqual(state, ctor1.InstallationState);
            Assert.AreEqual(0, ctor1.Errors.Count);
            Assert.IsTrue(ctor1.Success);
            Assert.IsFalse(ctor1.Cancelled);

            var ctor2 = new LibraryInstallationResult(state, PredefinedErrors.ManifestMalformed());

            Assert.AreEqual(state, ctor2.InstallationState);
            Assert.AreEqual(1, ctor2.Errors.Count);
            Assert.IsFalse(ctor2.Success);
            Assert.IsFalse(ctor2.Cancelled);
        }
Exemple #7
0
        /// <summary>
        /// Creates an instance of the <see cref="Manifest"/> class based on
        /// the provided JSON string.
        /// </summary>
        /// <param name="json">A string of JSON in the correct format.</param>
        /// <param name="dependencies">The host provided dependencies.</param>
        /// <returns></returns>
        internal static Manifest FromJson(string json, IDependencies dependencies)
        {
            try
            {
                Manifest manifest = JsonConvert.DeserializeObject <Manifest>(json);
                manifest._dependencies    = dependencies;
                manifest._hostInteraction = dependencies.GetHostInteractions();

                UpdateLibraryProviderAndDestination(manifest);

                return(manifest);
            }
            catch (Exception)
            {
                dependencies.GetHostInteractions().Logger.Log(PredefinedErrors.ManifestMalformed().Message, LogLevel.Task);
                return(null);
            }
        }
        /// <summary>
        /// Creates an instance of the <see cref="Manifest"/> class based on
        /// the provided JSON string.
        /// </summary>
        /// <param name="json">A string of JSON in the correct format.</param>
        /// <param name="dependencies">The host provided dependencies.</param>
        /// <returns></returns>
        public static Manifest FromJson(string json, IDependencies dependencies)
        {
            try
            {
                Manifest manifest = JsonConvert.DeserializeObject <Manifest>(json);
                manifest._dependencies    = dependencies;
                manifest._hostInteraction = dependencies.GetHostInteractions();

                foreach (LibraryInstallationState state in manifest.Libraries.Cast <LibraryInstallationState>())
                {
                    state.ProviderId = state.ProviderId ?? manifest.DefaultProvider;
                }

                return(manifest);
            }
            catch (Exception)
            {
                dependencies.GetHostInteractions().Logger.Log(PredefinedErrors.ManifestMalformed().Message, LogLevel.Task);
                return(null);
            }
        }
        private void OnFileSaved(object sender, TextDocumentFileActionEventArgs e)
        {
            var textDocument = sender as ITextDocument;

            if (e.FileActionType == FileActionTypes.ContentSavedToDisk && textDocument != null)
            {
                Task.Run(async() =>
                {
                    try
                    {
                        Manifest newManifest = Manifest.FromJson(textDocument.TextBuffer.CurrentSnapshot.GetText(), _dependencies);

                        if (newManifest != null)
                        {
                            await RemoveFilesAsync(newManifest).ConfigureAwait(false);

                            _manifest = newManifest;

                            await LibraryHelpers.RestoreAsync(textDocument.FilePath, _manifest, CancellationToken.None).ConfigureAwait(false);
                            Telemetry.TrackOperation("restoresave");
                        }
                        else
                        {
                            AddErrorToList(PredefinedErrors.ManifestMalformed());
                        }
                    }
                    catch (Exception ex)
                    {
                        string textMessage = string.Concat(Environment.NewLine, LibraryManager.Resources.Text.RestoreHasErrors, Environment.NewLine);

                        Logger.LogEvent(textMessage, LogLevel.Task);
                        Logger.LogEvent(ex.ToString(), LogLevel.Error);
                        Telemetry.TrackException("restoresavefailed", ex);
                    }
                });
            }
        }
        private async Task UninstallLibraryAsync(string configFilePath, string libraryId, CancellationToken cancellationToken)
        {
            Logger.LogEventsHeader(OperationType.Uninstall, libraryId);

            try
            {
                Stopwatch sw = new Stopwatch();
                sw.Start();

                var      dependencies = Dependencies.FromConfigFile(configFilePath);
                Manifest manifest     = await Manifest.FromFileAsync(configFilePath, dependencies, cancellationToken).ConfigureAwait(false);

                ILibraryOperationResult result = null;

                if (manifest == null)
                {
                    result = LibraryOperationResult.FromError(PredefinedErrors.ManifestMalformed());
                }
                else
                {
                    IHostInteraction hostInteraction = dependencies.GetHostInteractions();
                    result = await manifest.UninstallAsync(libraryId, async (filesPaths) => await hostInteraction.DeleteFilesAsync(filesPaths, cancellationToken), cancellationToken).ConfigureAwait(false);
                }

                sw.Stop();

                Logger.LogEventsSummary(new List <ILibraryOperationResult> {
                    result
                }, OperationType.Uninstall, sw.Elapsed);
                Telemetry.TrackUserTask("libraryuninstall");
            }
            catch (OperationCanceledException)
            {
                Logger.LogEvent(string.Format(LibraryManager.Resources.Text.Uninstall_LibraryCancelled, libraryId), LogLevel.Task);
            }
        }
        private async Task ExecuteAsync(object sender, EventArgs e)
        {
            Telemetry.TrackUserTask("Execute-InstallLibraryCommand");

            ProjectItem item = await VsHelpers.GetSelectedItemAsync().ConfigureAwait(false);

            Project project = await VsHelpers.GetProjectOfSelectedItemAsync().ConfigureAwait(false);

            if (project != null)
            {
                string rootFolder = await project.GetRootFolderAsync().ConfigureAwait(false);

                string        configFilePath = Path.Combine(rootFolder, Constants.ConfigFileName);
                IDependencies dependencies   = Dependencies.FromConfigFile(configFilePath);

                Manifest manifest = await GetManifestAsync(configFilePath, dependencies).ConfigureAwait(false);

                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                // If the manifest contains errors, we will not invoke the "Add Client-Side libraries" dialog
                // Instead we will display a message box indicating the syntax errors in manifest file.
                if (manifest == null)
                {
                    IVsUIShell shell = Package.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell;
                    int        result;

                    shell.ShowMessageBox(dwCompRole: 0,
                                         rclsidComp: Guid.Empty,
                                         pszTitle: null,
                                         pszText: PredefinedErrors.ManifestMalformed().Message,
                                         pszHelpFile: null,
                                         dwHelpContextID: 0,
                                         msgbtn: OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                         msgdefbtn: OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                         msgicon: OLEMSGICON.OLEMSGICON_WARNING,
                                         fSysAlert: 0,
                                         pnResult: out result);

                    return;
                }

                string target = string.Empty;

                // Install command was invoked from a folder.
                // So the initial target location should be name of the folder from which
                // the command was invoked.
                if (item != null)
                {
                    target = item.FileNames[1];
                }
                else
                {
                    // Install command was invoked from project scope.
                    // If wwwroot exists, initial target location should be - wwwroot/lib.
                    // Else, target location should be - lib
                    if (Directory.Exists(Path.Combine(rootFolder, "wwwroot")))
                    {
                        target = Path.Combine(rootFolder, "wwwroot", "lib") + Path.DirectorySeparatorChar;
                    }
                    else
                    {
                        target = Path.Combine(rootFolder, "lib") + Path.DirectorySeparatorChar;
                    }
                }

                UI.InstallDialog dialog = new UI.InstallDialog(dependencies, _libraryCommandService, configFilePath, target, rootFolder, project);

                var dte  = (DTE)Package.GetGlobalService(typeof(SDTE));
                int hwnd = dte.MainWindow.HWnd;
                WindowInteropHelper windowInteropHelper = new WindowInteropHelper(dialog);

                // Set visual studio window's handle as the owner of the dialog.
                // This will remove the dialog from alt-tab list and will not allow the user to switch the dialog box to the background
                windowInteropHelper.Owner = new IntPtr(hwnd);

                dialog.ShowDialog();

                Telemetry.TrackUserTask("Open-InstallDialog");
            }
        }
        private async Task ExecuteAsync(object sender, EventArgs e)
        {
            Telemetry.TrackUserTask("Execute-InstallLibraryCommand");

            ProjectItem item = await VsHelpers.GetSelectedItemAsync().ConfigureAwait(false);

            Project project = await VsHelpers.GetProjectOfSelectedItemAsync().ConfigureAwait(false);

            if (project != null)
            {
                string rootFolder = await project.GetRootFolderAsync().ConfigureAwait(false);

                string        configFilePath = Path.Combine(rootFolder, Constants.ConfigFileName);
                IDependencies dependencies   = _dependenciesFactory.FromConfigFile(configFilePath);

                Manifest manifest = await GetManifestAsync(configFilePath, dependencies).ConfigureAwait(false);

                await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();

                // If the manifest contains errors, we will not invoke the "Add Client-Side libraries" dialog
                // Instead we will display a message box indicating the syntax errors in manifest file.
                if (manifest == null)
                {
                    IVsUIShell shell = Package.GetGlobalService(typeof(SVsUIShell)) as IVsUIShell;
                    int        result;

                    shell.ShowMessageBox(dwCompRole: 0,
                                         rclsidComp: Guid.Empty,
                                         pszTitle: null,
                                         pszText: PredefinedErrors.ManifestMalformed().Message,
                                         pszHelpFile: null,
                                         dwHelpContextID: 0,
                                         msgbtn: OLEMSGBUTTON.OLEMSGBUTTON_OK,
                                         msgdefbtn: OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,
                                         msgicon: OLEMSGICON.OLEMSGICON_WARNING,
                                         fSysAlert: 0,
                                         pnResult: out result);

                    return;
                }

                string target = string.Empty;

                // Install command was invoked from a folder.
                // So the initial target location should be name of the folder from which
                // the command was invoked.
                if (item != null)
                {
                    target = item.FileNames[1];
                }
                else
                {
                    // Install command was invoked from project scope.
                    // If wwwroot exists, initial target location should be - wwwroot/lib.
                    // Else, target location should be - lib
                    if (Directory.Exists(Path.Combine(rootFolder, "wwwroot")))
                    {
                        target = Path.Combine(rootFolder, "wwwroot", "lib") + Path.DirectorySeparatorChar;
                    }
                    else
                    {
                        target = Path.Combine(rootFolder, "lib") + Path.DirectorySeparatorChar;
                    }
                }

                string initialTargetLocation = CalculateSuggestedInstallPath(target, rootFolder);


                var selectedProviderBinding = new SelectedProviderBinding();
                var libraryIdViewModel      = new LibraryIdViewModel(new ProviderCatalogSearchService(() => selectedProviderBinding.SelectedProvider),
                                                                     string.Empty);

                var libraryNameBinding      = new LibraryNameBinding();
                var targetLocationViewModel = new TargetLocationViewModel(initialTargetLocation,
                                                                          libraryNameBinding,
                                                                          new LocationSearchService(dependencies.GetHostInteractions()));

                var dialogViewModel = new InstallDialogViewModel(
                    _libraryCommandService,
                    configFilePath,
                    dependencies,
                    libraryIdViewModel,
                    targetLocationViewModel,
                    selectedProviderBinding,
                    libraryNameBinding,
                    target,
                    project);

                var dialog = new UI.InstallDialog(dialogViewModel);
                dialog.ShowModal();

                Telemetry.TrackUserTask("Open-InstallDialog");
            }
        }
Exemple #13
0
        /// <summary>
        /// Returns a collection of <see cref="ILibraryOperationResult"/> that represents the status for validation of the Manifest and its libraries
        /// </summary>
        /// <param name="manifest">The <see cref="Manifest"/> to be validated</param>
        /// <param name="dependencies"><see cref="IDependencies"/>used to validate the libraries</param>
        /// <param name="cancellationToken"></param>
        /// <returns></returns>
        public static async Task <IEnumerable <ILibraryOperationResult> > GetManifestErrorsAsync(
            Manifest manifest,
            IDependencies dependencies,
            CancellationToken cancellationToken)
        {
            cancellationToken.ThrowIfCancellationRequested();

            if (manifest == null)
            {
                return(new ILibraryOperationResult[] { LibraryOperationResult.FromError(PredefinedErrors.ManifestMalformed()) });
            }

            if (!IsValidManifestVersion(manifest.Version))
            {
                return(new ILibraryOperationResult[] { LibraryOperationResult.FromError(PredefinedErrors.VersionIsNotSupported(manifest.Version)) });
            }

            return(await GetLibrariesErrorsAsync(manifest.Libraries, dependencies, manifest.DefaultDestination, manifest.DefaultProvider, cancellationToken));
        }