/// <summary> /// Get set of dependencies for project that are not installed or not up to date /// </summary> /// <param name="package">Package to be checked</param> /// <returns>enumerable INpmInstalledPackage set</returns> public IEnumerable<INpmPackageDependency> FindDependenciesToBeInstalled(INpmPackage package) { if (package == null) { // check everything return this.ApiClient.Outdated(); } else { // check specific package, and if it has dependencies // then change to package directory and check children if (string.IsNullOrWhiteSpace(package.Name)) { throw new ArgumentException("package.name is required"); } IEnumerable<INpmPackageDependency> outdatedList = this.ApiClient.Outdated(package.Name); IEnumerable<INpmInstalledPackage> beforePackages = this.ApiClient.List(); IEnumerable<INpmInstalledPackage> matchedList = beforePackages.Where(r => r.Name == package.Name).AsEnumerable(); if (matchedList != null && matchedList.Count() > 0) { INpmInstalledPackage matched = matchedList.First(); if (matched != null && matched.HasDependencies) { if (!string.IsNullOrWhiteSpace(matched.Name)) { this.ApiClient.SetDependencyDirectory(matched.Name); } IEnumerable<INpmPackageDependency> outdatedChildren = this.ApiClient.Outdated(); if (outdatedChildren != null && outdatedChildren.Count() > 0) { outdatedList = outdatedList.Concat(outdatedChildren); } this.ApiClient.SetDependencyDirectory(null); } } return outdatedList; } }
/// <summary> /// Uninstall specified package from current project /// </summary> /// <param name="package">name of package</param> public void UninstallPackage(INpmPackage package) { if (package == null) { throw new ArgumentNullException("package"); } this.ApiClient.Uninstall(package.Name); }
/// <summary> /// Update specified package in current directory /// </summary> /// <param name="package">name and optional version</param> public void UpdatePackage(INpmPackage package) { if (package == null) { throw new ArgumentNullException("package"); } if (string.IsNullOrWhiteSpace(package.Name)) { throw new ArgumentException("package.name is required"); } // first update this package by name IEnumerable<INpmInstalledPackage> updatedList = this.ApiClient.Update(package.Name); IEnumerable<INpmInstalledPackage> beforePackages = this.ApiClient.ListChildren(); // find package, and build path if needed IEnumerable<INpmInstalledPackage> matchedList = beforePackages.Where(r => r.Name == package.Name).AsEnumerable(); INpmInstalledPackage matched = null; if (matchedList != null && matchedList.Count() > 0) { matched = matchedList.First(); } // update the package descendents if (matched != null && matched.HasDependencies) { if (!string.IsNullOrWhiteSpace(matched.Name)) { this.ApiClient.SetDependencyDirectory(matched.Name); } IEnumerable<INpmInstalledPackage> updatedChildren = this.ApiClient.Update(null); this.ApiClient.SetDependencyDirectory(null); } }
/// <summary> /// Install sepcified package /// </summary> /// <param name="package">name and optional version to be installed</param> public void InstallPackage(INpmPackage package) { this.ApiClient.Install(package); }
/// <summary> /// Test if the package is installed in current project /// </summary> /// <param name="package">name and optional version to test</param> /// <returns>INpmInstalledPackage or null</returns> public INpmInstalledPackage IsPackageInstalled(INpmPackage package) { IEnumerable<INpmInstalledPackage> children = this.ApiClient.ListChildren(); if (children != null && children.Count() > 0) { foreach (INpmInstalledPackage child in children) { if (child.Name == package.Name && !child.IsMissing) { // if version specified, match version as well as name if (!string.IsNullOrWhiteSpace(package.Version)) { if (child.Version == package.Version) { return child; } else { return null; } } return child; } } } return null; }
/// <summary> /// Deserialize the parsed json results and try to match package /// </summary> /// <param name="package">Package that has name to match</param> /// <param name="name">name of package</param> /// <param name="dependentPath">list of parents delimited by "/"</param> /// <param name="listObj">dictionary at root of package</param> /// <returns>Installed package object</returns> /// <remarks>This is called recursively as a dependency is a package</remarks> protected NpmInstalledPackage MatchPackageFromDictionary( INpmPackage package, string name, string dependentPath, Dictionary<string, object> listObj) { // if name matches and not missing, create package and return it if (package.Name == name && !listObj.ContainsKey("missing")) { NpmInstalledPackage installed = new NpmInstalledPackage(); installed.Name = name; installed.DependentPath = dependentPath; if (listObj.ContainsKey("version")) { installed.Version = listObj["version"] as string; } if (listObj.ContainsKey("invalid")) { installed.IsOutdated = true; } if (listObj.ContainsKey("dependencies")) { installed.HasDependencies = true; } return installed; } // look in the dependencies if (listObj.ContainsKey("dependencies")) { IDictionary<string, object> dependDict = null; object dependencyObj; if (listObj.TryGetValue("dependencies", out dependencyObj)) { dependDict = dependencyObj as IDictionary<string, object>; } if (dependDict != null && dependDict.Count > 0) { string mypath = string.IsNullOrWhiteSpace(dependentPath) ? name : dependentPath + "/" + name; foreach (KeyValuePair<string, object> pair in dependDict) { Dictionary<string, object> val = pair.Value as Dictionary<string, object>; if (val != null) { NpmInstalledPackage installed = this.MatchPackageFromDictionary(package, pair.Key, mypath, val); if (installed != null) { return installed; } } } } } return null; }
/// <summary> /// Set package name and version from string name@version /// </summary> /// <param name="package">INpmPackage to update</param> /// <param name="nameVersion">string name or name@version</param> protected static void FillPackageFromNameVersion(INpmPackage package, string nameVersion) { if (nameVersion == null) { package.Name = null; package.Version = null; } else { char[] seps = new char[] { '@' }; string[] nameAndVersion = nameVersion.Split(seps); if (nameAndVersion.Length > 1) { package.Name = nameAndVersion[0]; package.Version = nameAndVersion[1]; } else { package.Name = nameAndVersion[0]; package.Version = null; } } }
/// <summary> /// parse npm list output for matching NpmInstalledPackage /// </summary> /// <param name="listJson">text output</param> /// <param name="package">Installed package with name to match</param> /// <returns>NpmInstalledPackage properties or null</returns> public INpmInstalledPackage FromListMatchInstalled(string listJson, INpmPackage package) { JavaScriptSerializer serializer = new JavaScriptSerializer(); INpmInstalledPackage matched = null; Dictionary<string, object> listObj = null; try { listObj = serializer.Deserialize<Dictionary<string, object>>(listJson); } catch (InvalidOperationException ex) { throw new NpmException(ParseErrorList, ex); } catch (ArgumentException ex) { throw new NpmException(ParseErrorList, ex); } try { if (listObj != null && listObj.Count > 0) { object name = string.Empty; listObj.TryGetValue("name", out name); matched = this.MatchPackageFromDictionary(package, name as string, string.Empty, listObj); } } catch (Exception ex) { throw new NpmException(ConvertErrorList, ex); } return matched; }
/// <summary> /// Check if package is installed. Wraps 'npm list' and looks for match /// </summary> /// <param name="package">name and version to install</param> /// <returns>NpmInstalledPackage or null</returns> public INpmInstalledPackage TestInstalled(INpmPackage package) { int rc = this.Client.Execute("list", "--json"); if (rc == 0) { string output = this.Client.LastExecuteOutput; return this.Serializer.FromListMatchInstalled(output, package); } if (!string.IsNullOrWhiteSpace(this.Client.LastExecuteErrorText)) { throw this.Serializer.ExceptionFromError(this.Client.LastExecuteErrorText); } return null; }
/// <summary> /// Install a npm package. Wraps 'npm install name' /// </summary> /// <param name="package">name and version to install</param> /// <returns>enumerable list of packages</returns> public IEnumerable<INpmInstalledPackage> Install(INpmPackage package) { if (package == null) { throw new ArgumentNullException("package"); } if (string.IsNullOrWhiteSpace(package.Name)) { throw new ArgumentException("package name is required"); } string args; if (!string.IsNullOrWhiteSpace(package.Version)) { args = package.Name + "@" + package.Version; } else { args = package.Name; } int rc = this.Client.Execute("install", args + " --json"); if (rc == 0) { string output = this.Client.LastExecuteOutput; return this.Serializer.FromInstall(output); } if (!string.IsNullOrWhiteSpace(this.Client.LastExecuteErrorText)) { throw this.Serializer.ExceptionFromError(this.Client.LastExecuteErrorText); } return null; }