Ejemplo n.º 1
0
        protected override void UpgradeProject(ref ProjectRootElement projectXml, ref ProjectRootElement userProjectXml, Action <__VSUL_ERRORLEVEL, string> log)
        {
            var envVarsProp = projectXml.Properties.FirstOrDefault(p => p.Name == NodejsConstants.EnvironmentVariables);

            if (envVarsProp != null)
            {
                var globals = projectXml.PropertyGroups.FirstOrDefault() ?? projectXml.AddPropertyGroup();
                AddOrSetProperty(globals, NodejsConstants.Environment, envVarsProp.Value.Replace(";", "\r\n"));
                envVarsProp.Parent.RemoveChild(envVarsProp);
                log(__VSUL_ERRORLEVEL.VSUL_INFORMATIONAL, SR.GetString(SR.UpgradedEnvironmentVariables));
            }
        }
Ejemplo n.º 2
0
        public async Task <ExecutionResult> Execute(IReplWindow window, string arguments)
        {
            string projectPath  = string.Empty;
            string npmArguments = arguments.Trim(' ', '\t');

            // Parse project name/directory in square brackets
            if (npmArguments.StartsWith("[", StringComparison.Ordinal))
            {
                var match = Regex.Match(npmArguments, @"(?:[[]\s*\""?\s*)(.*?)(?:\s*\""?\s*[]]\s*)");
                projectPath  = match.Groups[1].Value;
                npmArguments = npmArguments.Substring(match.Length);
            }

            // Include spaces on either side of npm arguments so that we can more simply detect arguments
            // at beginning and end of string (e.g. '--global')
            npmArguments = string.Format(CultureInfo.InvariantCulture, " {0} ", npmArguments);

            // Prevent running `npm init` without the `-y` flag since it will freeze the repl window,
            // waiting for user input that will never come.
            if (npmArguments.Contains(" init ") && !(npmArguments.Contains(" -y ") || npmArguments.Contains(" --yes ")))
            {
                window.WriteError(SR.GetString(SR.ReplWindowNpmInitNoYesFlagWarning));
                return(ExecutionResult.Failure);
            }

            var solution = Package.GetGlobalService(typeof(SVsSolution)) as IVsSolution;
            IEnumerable <IVsProject> loadedProjects = solution.EnumerateLoadedProjects(onlyNodeProjects: false);

            var projectNameToDirectoryDictionary = new Dictionary <string, Tuple <string, IVsHierarchy> >(StringComparer.OrdinalIgnoreCase);

            foreach (IVsProject project in loadedProjects)
            {
                var    hierarchy = (IVsHierarchy)project;
                object extObject;

                var projectResult = hierarchy.GetProperty(VSConstants.VSITEMID_ROOT, (int)__VSHPROPID.VSHPROPID_ExtObject, out extObject);
                if (!ErrorHandler.Succeeded(projectResult))
                {
                    continue;
                }

                EnvDTE.Project dteProject = extObject as EnvDTE.Project;
                if (dteProject == null)
                {
                    continue;
                }

                string projectName = dteProject.Name;
                if (string.IsNullOrEmpty(projectName))
                {
                    continue;
                }

                // Try checking the `ProjectHome` property first
                EnvDTE.Properties properties = dteProject.Properties;
                if (dteProject.Properties != null)
                {
                    EnvDTE.Property projectHome = null;
                    try {
                        projectHome = properties.Item("ProjectHome");
                    } catch (ArgumentException) {
                        // noop
                    }

                    if (projectHome != null)
                    {
                        var projectHomeDirectory = projectHome.Value as string;
                        if (!string.IsNullOrEmpty(projectHomeDirectory))
                        {
                            projectNameToDirectoryDictionary.Add(projectName, Tuple.Create(projectHomeDirectory, hierarchy));
                            continue;
                        }
                    }
                }

                // Otherwise, fall back to using fullname
                string projectDirectory = string.IsNullOrEmpty(dteProject.FullName) ? null : Path.GetDirectoryName(dteProject.FullName);
                if (!string.IsNullOrEmpty(projectDirectory))
                {
                    projectNameToDirectoryDictionary.Add(projectName, Tuple.Create(projectDirectory, hierarchy));
                }
            }

            Tuple <string, IVsHierarchy> projectInfo;

            if (string.IsNullOrEmpty(projectPath) && projectNameToDirectoryDictionary.Count == 1)
            {
                projectInfo = projectNameToDirectoryDictionary.Values.First();
            }
            else
            {
                projectNameToDirectoryDictionary.TryGetValue(projectPath, out projectInfo);
            }

            NodejsProjectNode nodejsProject = null;

            if (projectInfo != null)
            {
                projectPath = projectInfo.Item1;
                if (projectInfo.Item2 != null)
                {
                    nodejsProject = projectInfo.Item2.GetProject().GetNodejsProject();
                }
            }

            bool isGlobalCommand = false;

            if (string.IsNullOrWhiteSpace(npmArguments) ||
                npmArguments.Contains(" -g ") || npmArguments.Contains(" --global "))
            {
                projectPath     = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
                isGlobalCommand = true;
            }

            // In case someone copies filename
            string projectDirectoryPath = File.Exists(projectPath) ? Path.GetDirectoryName(projectPath) : projectPath;

            if (!isGlobalCommand && !Directory.Exists(projectDirectoryPath))
            {
                window.WriteError("Please specify a valid Node.js project or project directory. If your solution contains multiple projects, specify a target project using .npm [ProjectName or ProjectDir] <npm arguments> For example: .npm [MyApp] list");
                return(ExecutionResult.Failure);
            }

            string npmPath;

            try {
                npmPath = NpmHelpers.GetPathToNpm(
                    nodejsProject != null ?
                    Nodejs.GetAbsoluteNodeExePath(
                        nodejsProject.ProjectHome,
                        nodejsProject.GetProjectProperty(NodeProjectProperty.NodeExePath))
                        : null);
            } catch (NpmNotFoundException) {
                Nodejs.ShowNodejsNotInstalled();
                return(ExecutionResult.Failure);
            }

            var npmReplRedirector = new NpmReplRedirector(window);

            await ExecuteNpmCommandAsync(
                npmReplRedirector,
                npmPath,
                projectDirectoryPath,
                new[] { npmArguments },
                null);

            if (npmReplRedirector.HasErrors)
            {
                window.WriteError(SR.GetString(SR.NpmReplCommandCompletedWithErrors, arguments));
            }
            else
            {
                window.WriteLine(SR.GetString(SR.NpmSuccessfullyCompleted, arguments));
            }

            if (nodejsProject != null)
            {
                await nodejsProject.CheckForLongPaths(npmArguments);
            }

            return(ExecutionResult.Success);
        }
Ejemplo n.º 3
0
        private OutputWindowRedirector GetNpmOutputPane()
        {
            try {
#if DEV14_OR_LATER
                return(OutputWindowRedirector.Get(_projectNode.Site, VSPackageManagerPaneGuid, "Bower/npm"));
#else
                return(OutputWindowRedirector.Get(_projectNode.Site, NpmOutputPaneGuid, SR.GetString(SR.NpmOutputPaneTitle)));
#endif
            } catch (InvalidOperationException) {
                return(null);
            }
        }
Ejemplo n.º 4
0
        public async Task CheckForLongPaths(string npmArguments = null) {
            if (_isCheckingForLongPaths || !NodejsPackage.Instance.GeneralOptionsPage.CheckForLongPaths) {
                return;
            }

            if (npmArguments != null && _uninstallRegex.IsMatch(npmArguments)) {
                return;
            }

            try {
                _isCheckingForLongPaths = true;
                TaskDialogButton dedupeButton, ignoreButton, disableButton;
                var taskDialog = new TaskDialog(NodejsPackage.Instance) {
                    AllowCancellation = true,
                    EnableHyperlinks = true,
                    Title = SR.GetString(SR.LongPathWarningTitle),
                    MainIcon = TaskDialogIcon.Warning,
                    Content = SR.GetString(SR.LongPathWarningText),
                    CollapsedControlText = SR.GetString(SR.LongPathShowPathsExceedingTheLimit),
                    ExpandedControlText = SR.GetString(SR.LongPathHidePathsExceedingTheLimit),
                    Buttons = {
                        (dedupeButton = new TaskDialogButton(SR.GetString(SR.LongPathNpmDedupe), SR.GetString(SR.LongPathNpmDedupeDetail))),
                        (ignoreButton = new TaskDialogButton(SR.GetString(SR.LongPathDoNothingButWarnNextTime))),
                        (disableButton = new TaskDialogButton(SR.GetString(SR.LongPathDoNothingAndDoNotWarnAgain), SR.GetString(SR.LongPathDoNothingAndDoNotWarnAgainDetail)))
                    },
                    FooterIcon = TaskDialogIcon.Information,
                    Footer = SR.GetString(SR.LongPathFooter)
                };

                taskDialog.HyperlinkClicked += (sender, e) => {
                    switch (e.Url) {
                        case "#msdn":
                            Process.Start("http://go.microsoft.com/fwlink/?LinkId=454508");
                            break;
                        case "#uservoice":
                            Process.Start("http://go.microsoft.com/fwlink/?LinkID=456509");
                            break;
                        case "#help":
                            Process.Start("http://go.microsoft.com/fwlink/?LinkId=456511");
                            break;
                        default:
                            System.Windows.Clipboard.SetText(e.Url);
                            break;
                    }
                };

                recheck:

                var longPaths = await Task.Factory.StartNew(() =>
                    GetLongSubPaths(ProjectHome)
                    .Concat(GetLongSubPaths(_intermediateOutputPath))
                    .Select(lpi => string.Format("• {1}\u00A0<a href=\"{0}\">{2}</a>", lpi.FullPath, lpi.RelativePath, SR.GetString(SR.LongPathClickToCopy)))
                    .ToArray());
                if (longPaths.Length == 0) {
                    return;
                }
                taskDialog.ExpandedInformation = string.Join("\r\n", longPaths);

                var button = taskDialog.ShowModal();
                if (button == dedupeButton) {
                    var repl = NodejsPackage.Instance.OpenReplWindow(focus: false);
                    await repl.ExecuteCommand(".npm dedupe").HandleAllExceptions(SR.ProductName);

                    taskDialog.Content += "\r\n\r\n" + SR.GetString(SR.LongPathNpmDedupeDidNotHelp);
                    taskDialog.Buttons.Remove(dedupeButton);
                    goto recheck;
                } else if (button == disableButton) {
                    var page = NodejsPackage.Instance.GeneralOptionsPage;
                    page.CheckForLongPaths = false;
                    page.SaveSettingsToStorage();
                }
            } finally {
                _isCheckingForLongPaths = false;
            }
        }