private static async Task <IEnumerable <DependencyError> > GetDependencyErrors(string packageName, PackageLockDependency dependency, string nodeModulesPath) { var packagePath = Path.GetFullPath(Path.Combine(nodeModulesPath, packageName)); var packageJsonPath = Path.Combine(packagePath, "package.json"); Interlocked.Increment(ref _checkedDependencies); if (!File.Exists(packageJsonPath)) { return(new[] { new DependencyError(packageName, dependency.Version, "None") }); } var packageJson = await JsonAccess.LoadPackageJson(packageJsonPath); var errors = new List <DependencyError>(); if (packageJson.Version != dependency.Version) { errors.Add(new DependencyError(packageName, dependency.Version, packageJson.Version)); } var nestedNodeModulesPath = Path.Combine(packagePath, "node_modules"); var tasks = dependency.Dependencies.Select(kvp => GetDependencyErrors(kvp.Key, kvp.Value, nestedNodeModulesPath)).ToArray(); var nestedDependencyErrors = await Task.WhenAll(tasks); var flattenedNestedDependencyErrors = nestedDependencyErrors.SelectMany(x => x); errors.AddRange(flattenedNestedDependencyErrors); return(errors); }
public static async Task <int> Main() { var projectPath = Directory.GetCurrentDirectory(); var packageLockPath = Path.Combine(projectPath, "package-lock.json"); if (!File.Exists(packageLockPath)) { Console.Error.WriteLine("'package-lock.json' not found in current directory."); return(-1); } var packageLock = await JsonAccess.LoadPackageLockJson(packageLockPath); var sw = Stopwatch.StartNew(); var nodeModulesPath = Path.Combine(projectPath, "node_modules"); var tasks = packageLock.Dependencies.Select(kvp => GetDependencyErrors(kvp.Key, kvp.Value, nodeModulesPath)).ToArray(); int exitCode = 0; try { var errors = await Task.WhenAll(tasks); var flattenedErrors = errors.SelectMany(x => x); foreach (var dependencyError in flattenedErrors) { exitCode++; Console.Error.WriteLine( "Version mismatch for package '{0}'! Wanted '{1}' but got '{2}'!", dependencyError.PackageName, dependencyError.ExpectedVersion, dependencyError.ActualVersion); } } catch (Exception e) { Console.Error.WriteLine(e.Message); exitCode = -2; } sw.Stop(); Console.WriteLine("Checked {0} dependencies in {1}", _checkedDependencies, sw.Elapsed); return(exitCode); }