public RootPackage( string fullPathToRootDirectory, bool showMissingDevOptionalSubPackages, Dictionary <string, ModuleInfo> allModules = null, int depth = 0) { Path = fullPathToRootDirectory; var packageJsonFile = System.IO.Path.Combine(fullPathToRootDirectory, "package.json"); try { if (packageJsonFile.Length < 260) { PackageJson = PackageJsonFactory.Create(new DirectoryPackageJsonSource(fullPathToRootDirectory)); } } catch (RuntimeBinderException rbe) { throw new PackageJsonException( string.Format(@"Error processing package.json at '{0}'. The file was successfully read, and may be valid JSON, but the objects may not match the expected form for a package.json file. The following error was reported: {1}", packageJsonFile, rbe.Message), rbe); } try { Modules = new NodeModules(this, showMissingDevOptionalSubPackages, allModules, depth); } catch (PathTooLongException) { // otherwise we fail to create it completely... } }
protected override Task <List <FileDataValue> > ComputeFileDataValuesAsync(string filePath, CancellationToken cancellationToken) { Debug.Assert(PackageJsonFactory.IsPackageJsonFile(filePath), $"{filePath} should be a package.json file"); var packageJson = PackageJsonFactory.Create(this.EnsureRooted(filePath)); var main = packageJson.Main; var fileDataValues = new List <FileDataValue>(); if (!string.IsNullOrEmpty(main)) { var launchSettings = new PropertySettings { [LaunchConfigurationConstants.NameKey] = $"node {main} (package.json)", [LaunchConfigurationConstants.TypeKey] = "default" }; fileDataValues.Add(new FileDataValue( DebugLaunchActionContext.ContextTypeGuid, DebugLaunchActionContext.IsDefaultStartupProjectEntry, launchSettings, target: main)); // Target has to match the name used in the debug action context so it can be found during project configuration fileDataValues.Add(new FileDataValue(DebugLaunchActionContext.ContextTypeGuid, main, null, target: main)); // Also need a null target so that can be found for the context menu when querying for build configurations. // (See Microsoft.VisualStudio.Workspace.VSIntegration.UI.FileContextActionsCommandHandlersProvider.Provider.GetActionProviderForProjectConfiguration) fileDataValues.Add(new FileDataValue(DebugLaunchActionContext.ContextTypeGuid, main, null, target: null)); } return(Task.FromResult(fileDataValues)); }
public void TestReadFromDirectory() { var dir = TempFileManager.GetNewTempDirectory(); CreatePackageJson(Path.Combine(dir.FullName, "package.json"), PkgSimple); CheckPackage(PackageJsonFactory.Create(new DirectoryPackageJsonSource(dir.FullName))); }
private static IEnumerable <KeyValuePair <string, IPackageJson> > GetTopLevelPackageDirectories(string modulesBase) { var topLevelDirectories = Enumerable.Empty <string>(); if (Directory.Exists(modulesBase)) { try { topLevelDirectories = Directory.EnumerateDirectories(modulesBase); } catch (IOException) { // We want to handle DirectoryNotFound, DriveNotFound, PathTooLong } catch (UnauthorizedAccessException) { } } // Go through every directory in node_modules, and see if it's required as a top-level dependency foreach (var moduleDir in topLevelDirectories) { if (moduleDir.Length < NativeMethods.MAX_FOLDER_PATH && !_ignoredDirectories.Any(toIgnore => moduleDir.EndsWith(toIgnore))) { IPackageJson json = null; try { json = PackageJsonFactory.Create(new DirectoryPackageJsonSource(moduleDir)); } catch (PackageJsonException) { // Fail gracefully if there was an error parsing the package.json Debug.Fail("Failed to parse package.json in {0}", moduleDir); } if (json != null) { yield return(new KeyValuePair <string, IPackageJson>(moduleDir, json)); } } } }
public void ReadFromDirectory() { using (var manager = new TemporaryFileManager()) { var dir = manager.GetNewTempDirectory(); FilesystemPackageJsonTestHelpers.CreatePackageJson(Path.Combine(dir.FullName, "package.json"), PkgSimple); CheckPackage(PackageJsonFactory.Create(new DirectoryPackageJsonSource(dir.FullName))); } }
public RootPackage( string fullPathToRootDirectory, bool showMissingDevOptionalSubPackages, Dictionary <string, ModuleInfo> allModules = null, int depth = 0, int maxDepth = 1) { this.Path = fullPathToRootDirectory; var packageJsonFile = System.IO.Path.Combine(fullPathToRootDirectory, "package.json"); try { if (packageJsonFile.Length < 260) { this.PackageJson = PackageJsonFactory.Create(new DirectoryPackageJsonSource(fullPathToRootDirectory)); } } catch (RuntimeBinderException rbe) { throw new PackageJsonException( string.Format(CultureInfo.CurrentCulture, @"Error processing package.json at '{0}'. The file was successfully read, and may be valid JSON, but the objects may not match the expected form for a package.json file. The following error was reported: {1}", packageJsonFile, rbe.Message), rbe); } try { this.Modules = new NodeModules(this, showMissingDevOptionalSubPackages, allModules, depth, maxDepth); } catch (PathTooLongException) { // otherwise we fail to create it completely... } if (this.PackageJson != null) { this.Name = this.PackageJson.Name; } else { // this is the root package so the full folder name after node_nodules is the name // of the package var index = this.Path.IndexOf(NodejsConstants.NodeModulesFolderWithSeparators, StringComparison.OrdinalIgnoreCase); Debug.Assert(index > -1, "Failed to find the node_modules folder."); var name = this.Path.Substring(index + NodejsConstants.NodeModulesFolderWithSeparators.Length); this.Name = name; } }
public void DiscoverTests(IEnumerable <string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { AssemblyResolver.SetupHandler(); foreach (var source in sources) { // we're only interested in package.json files here. if (PackageJsonFactory.IsPackageJsonFile(source)) { this.DiscoverTestFiles(source, logger, discoverySink); } } }
private async void ExecDebugAsync(WorkspaceVisualNodeBase node) { var workspace = node.Workspace; var packageJson = PackageJsonFactory.Create(((IFileNode)node).FullPath); //invoke debuglaunchtargetprovider on this file var fileContextActions = await node.Workspace.GetFileContextActionsAsync(packageJson.Main, new[] { DebugLaunchActionContext.ContextTypeGuid }); if (fileContextActions.Any()) { // we requested a single context, so there should be a single grouping. Use the First action, since they're ordered by priority. var action = fileContextActions.Single().FirstOrDefault(); Debug.Assert(action != null, "Why is action null, when we did get a fileContextActions?"); await action.ExecuteAsync(DefaultBuildProgressUpdater, CancellationToken.None); } }
protected override Task <List <FileReferenceInfo> > ComputeFileReferencesAsync(string filePath, CancellationToken cancellationToken) { Debug.Assert(PackageJsonFactory.IsPackageJsonFile(filePath), $"{filePath} should be a package.json file"); var packageJson = PackageJsonFactory.Create(filePath); var main = packageJson.Main; var fileReferences = new List <FileReferenceInfo> { new FileReferenceInfo(main, context: "Debug", target: main, referenceType: (int)FileReferenceInfoType.Output) }; return(Task.FromResult(fileReferences)); }
public void DiscoverTests(IEnumerable <string> sources, IDiscoveryContext discoveryContext, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { AssemblyResolver.SetupHandler(); var settings = new UnitTestSettings(discoveryContext.RunSettings); this.frameworkDiscoverer = this.frameworkDiscoverer ?? new FrameworkDiscoverer(settings.TestFrameworksLocation); foreach (var source in sources) { // we're only interested in package.json files here. if (PackageJsonFactory.IsPackageJsonFile(source)) { this.DiscoverTestFiles(source, logger, discoverySink); } } }
private static bool TryGetCommand(uint nCmdID, string filePath, out string commandName) { var index = nCmdID - PkgCmdId.cmdidWorkSpaceNpmDynamicScript; var packageJson = PackageJsonFactory.Create(filePath); Debug.Assert(packageJson != null, "Failed to create package.json"); var scripts = packageJson.Scripts; if (index < scripts.Length) { commandName = packageJson.Scripts[index].CommandName; return(true); } commandName = null; return(false); }
private INpmController CreateController(string packageJsonPath) { Debug.Assert(Path.IsPathRooted(packageJsonPath)); Debug.Assert(PackageJsonFactory.IsPackageJsonFile(packageJsonPath)); var projectHome = Path.GetDirectoryName(packageJsonPath); var npmController = NpmControllerFactory.Create( projectHome, NodejsConstants.NpmCachePath, isProject: false); npmController.ErrorLogged += this.WriteNpmOutput; npmController.ExceptionLogged += this.WriteNpmException; npmController.OutputLogged += this.WriteNpmOutput; return(npmController); }
internal void DiscoverTestFiles(string packageJsonPath, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { logger.SendMessage(TestMessageLevel.Informational, $"Parsing '{packageJsonPath}'."); var packageJson = PackageJsonFactory.Create(packageJsonPath); if (string.IsNullOrEmpty(packageJson.TestRoot)) { logger.SendMessage(TestMessageLevel.Informational, "No vsTestOptions|testRoot specified."); return; } var workingDir = Path.GetDirectoryName(packageJsonPath); var testFolderPath = Path.Combine(workingDir, packageJson.TestRoot); if (!Directory.Exists(testFolderPath)) { logger.SendMessage(TestMessageLevel.Error, $"Testroot '{packageJson.TestRoot}' doesn't exist."); return; } var testFx = default(TestFramework); foreach (var dep in packageJson.AllDependencies) { testFx = this.frameworkDiscoverer.GetFramework(dep.Name); if (testFx != null) { break; } } testFx = testFx ?? this.frameworkDiscoverer.GetFramework(TestFrameworkDirectories.ExportRunnerFrameworkName); var nodeExePath = Nodejs.GetPathToNodeExecutableFromEnvironment(); var worker = new TestDiscovererWorker(packageJsonPath, nodeExePath); worker.DiscoverTests(testFolderPath, testFx, logger, discoverySink, nameof(PackageJsonTestDiscoverer)); }
internal void DiscoverTestFiles(string packageJsonPath, IMessageLogger logger, ITestCaseDiscoverySink discoverySink) { logger.SendMessage(TestMessageLevel.Informational, $"Parsing '{packageJsonPath}'."); var packageJson = PackageJsonFactory.Create(packageJsonPath); if (string.IsNullOrEmpty(packageJson.TestRoot)) { logger.SendMessage(TestMessageLevel.Informational, "No vsTestOptions|testRoot specified."); return; } var workingDir = Path.GetDirectoryName(packageJsonPath); var testFolderPath = Path.Combine(workingDir, packageJson.TestRoot); if (!Directory.Exists(testFolderPath)) { logger.SendMessage(TestMessageLevel.Error, $"Testroot '{packageJson.TestRoot}' doesn't exist."); return; } TestFramework testFx = null; foreach (var dep in packageJson.AllDependencies) { testFx = FrameworkDiscoverer.Instance.Get(dep.Name); if (testFx != null) { break; } } testFx = testFx ?? FrameworkDiscoverer.Instance.Get("ExportRunner"); var nodeExePath = Nodejs.GetPathToNodeExecutableFromEnvironment(); if (!File.Exists(nodeExePath)) { logger.SendMessage(TestMessageLevel.Error, "Node.exe was not found. Please install Node.js before running tests."); return; } var fileList = Directory.GetFiles(testFolderPath, "*.js", SearchOption.AllDirectories); var files = string.Join(";", fileList); logger.SendMessage(TestMessageLevel.Informational, $"Processing: {files}"); var discoveredTestCases = testFx.FindTests(fileList, nodeExePath, logger, projectRoot: workingDir); if (!discoveredTestCases.Any()) { logger.SendMessage(TestMessageLevel.Warning, "Discovered 0 testcases."); return; } foreach (var discoveredTest in discoveredTestCases) { var qualifiedName = discoveredTest.FullyQualifiedName; const string indent = " "; logger.SendMessage(TestMessageLevel.Informational, $"{indent}Creating TestCase:{qualifiedName}"); //figure out the test source info such as line number var filePath = CommonUtils.GetAbsoluteFilePath(workingDir, discoveredTest.TestFile); var testcase = new TestCase(qualifiedName, NodejsConstants.PackageJsonExecutorUri, packageJsonPath) { CodeFilePath = filePath, LineNumber = discoveredTest.SourceLine, DisplayName = discoveredTest.TestName }; testcase.SetPropertyValue(JavaScriptTestCaseProperties.TestFramework, testFx.Name); testcase.SetPropertyValue(JavaScriptTestCaseProperties.WorkingDir, workingDir); testcase.SetPropertyValue(JavaScriptTestCaseProperties.ProjectRootDir, workingDir); testcase.SetPropertyValue(JavaScriptTestCaseProperties.NodeExePath, nodeExePath); testcase.SetPropertyValue(JavaScriptTestCaseProperties.TestFile, filePath); discoverySink.SendTestCase(testcase); } logger.SendMessage(TestMessageLevel.Informational, $"Processing finished for framework '{testFx.Name}'."); }
private bool QueryDebug(string filePath) { var packageJson = PackageJsonFactory.Create(filePath); return(!string.IsNullOrEmpty(packageJson.Main)); }
protected override Task <bool> IsValidFileAsync(string filePath) { return(Task.FromResult(PackageJsonFactory.IsPackageJsonFile(filePath))); }
private static bool EnsurePackageJson(WorkspaceVisualNodeBase node) { return(node is IFileNode fileNode && PackageJsonFactory.IsPackageJsonFile(fileNode.FileName)); }
public NodeModules(IRootPackage parent, bool showMissingDevOptionalSubPackages, Dictionary <string, ModuleInfo> allModulesToDepth = null, int depth = 0) { var modulesBase = Path.Combine(parent.Path, NodejsConstants.NodeModulesFolder); _allModules = allModulesToDepth ?? new Dictionary <string, ModuleInfo>(); // This is the first time NodeModules is being created. // Iterate through directories to add everything that's known to be top-level. if (depth == 0) { Debug.Assert(_allModules.Count == 0, "Depth is 0, but top-level modules have already been added."); IEnumerable <string> topLevelDirectories = Enumerable.Empty <string>(); try { topLevelDirectories = Directory.EnumerateDirectories(modulesBase); } catch (IOException) { // We want to handle DirectoryNotFound, DriveNotFound, PathTooLong } catch (UnauthorizedAccessException) { } // Go through every directory in node_modules, and see if it's required as a top-level dependency foreach (var moduleDir in topLevelDirectories) { if (moduleDir.Length < NativeMethods.MAX_FOLDER_PATH && !_ignoredDirectories.Any(toIgnore => moduleDir.EndsWith(toIgnore))) { var packageJson = PackageJsonFactory.Create(new DirectoryPackageJsonSource(moduleDir)); if (packageJson != null) { if (packageJson.RequiredBy.Count() > 0) { // All dependencies in npm v3 will have at least one element present in _requiredBy. // _requiredBy dependencies that begin with hash characters represent top-level dependencies foreach (var requiredBy in packageJson.RequiredBy) { if (requiredBy.StartsWith("#") || requiredBy == "/") { AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth); break; } } } else { // This dependency is a top-level dependency not added by npm v3 AddTopLevelModule(parent, showMissingDevOptionalSubPackages, moduleDir, depth); } } } } } if (modulesBase.Length < NativeMethods.MAX_FOLDER_PATH && parent.HasPackageJson) { // Iterate through all dependencies in package.json foreach (var dependency in parent.PackageJson.AllDependencies) { var moduleDir = modulesBase; // try to find folder by recursing up tree do { moduleDir = Path.Combine(moduleDir, dependency.Name); if (AddModuleIfNotExists(parent, moduleDir, showMissingDevOptionalSubPackages, depth, dependency)) { break; } var parentNodeModulesIndex = moduleDir.LastIndexOf(NodejsConstants.NodeModulesFolder, Math.Max(0, moduleDir.Length - NodejsConstants.NodeModulesFolder.Length - dependency.Name.Length - 1)); moduleDir = moduleDir.Substring(0, parentNodeModulesIndex + NodejsConstants.NodeModulesFolder.Length); } while (moduleDir.Contains(NodejsConstants.NodeModulesFolder)); } } _packagesSorted.Sort(new PackageComparer()); }
protected IPackageJson LoadFrom(TextReader reader) { return(PackageJsonFactory.Create(new ReaderPackageJsonSource(reader))); }
protected IPackageJson LoadFromFile(string fullPathToFile) { return(PackageJsonFactory.Create(new FilePackageJsonSource(fullPathToFile))); }
protected IPackageJson LoadFrom(string json) { return(PackageJsonFactory.Create(new MockPackageJsonSource(json))); }