/// <summary> /// Gets the dependencies of the given dependency. /// This is done by reading the .pom file for the BestVersion /// of the dependency. /// </summary> /// <returns>The dependencies.</returns> /// <param name="dep">Dependency to process</param> /// <param name="repoPaths">Set of additional repo paths to search for the /// dependencies.</param> internal static IEnumerable <Dependency> GetDependencies(Dependency dep, List <string> repoPaths) { List <Dependency> dependencyList = new List <Dependency>(); if (String.IsNullOrEmpty(dep.BestVersion)) { Log(String.Format("ERROR: No compatible versions of {0} found given the set of " + "required dependencies.\n\n{0} was referenced by:\n{1}\n\n", dep.Key, dep.CreatedBy)); return(dependencyList); } string basename = dep.Artifact + "-" + dep.BestVersion + ".pom"; string pomFile = Path.Combine(dep.BestVersionPath, basename); Log("GetDependencies - reading pom of " + basename + " pom: " + pomFile + " " + " versions: " + String.Join(", ", (new List <string>(dep.PossibleVersions)).ToArray()), verbose: true); XmlTextReader reader = new XmlTextReader(new StreamReader(pomFile)); bool inDependencies = false; bool inDep = false; string groupId = null; string artifactId = null; string version = null; while (reader.Read()) { if (reader.Name == "dependencies") { inDependencies = reader.IsStartElement(); } if (inDependencies && reader.Name == "dependency") { inDep = reader.IsStartElement(); } if (inDep && reader.Name == "groupId") { groupId = reader.ReadString(); } if (inDep && reader.Name == "artifactId") { artifactId = reader.ReadString(); } if (inDep && reader.Name == "version") { version = reader.ReadString(); } // if we ended the dependency, add it if (!string.IsNullOrEmpty(artifactId) && !inDep) { // Unfortunately, the Maven POM doesn't contain metadata to map the package // to each Android SDK package ID so the list "packageIds" is left as null in // this case. Dependency d = FindCandidate(new Dependency(groupId, artifactId, version), repoPaths); if (d == null) { throw new ResolutionException("Cannot find candidate artifact for " + groupId + ":" + artifactId + ":" + version); } groupId = null; artifactId = null; version = null; dependencyList.Add(d); } } return(dependencyList); }
internal IEnumerable <Dependency> GetDependencies(Dependency dep) { return(GetDependencies(dep, repositoryPaths)); }
/// <summary> /// Get the current set of dependencies referenced by the project. /// </summary> /// <param name="dependencies">Dependencies to search for in the specified /// directory.</param> /// <param name="destDirectory">Directory where dependencies are located in the /// project.</param> /// <param name="explodeAar">Delegate that determines whether a dependency should be /// exploded. If a dependency is currently exploded but shouldn't be according to this /// delegate, the dependency is deleted.</param> /// <param name="repoPaths">Set of additional repo paths to search for the /// dependencies.</param> /// <returns>Dictionary indexed by Dependency.Key where each item is a tuple of /// Dependency instance and the path to the dependency in destDirectory.</returns> public static Dictionary <string, KeyValuePair <Dependency, string> > GetCurrentDependencies( Dictionary <string, Dependency> dependencies, string destDirectory, ExplodeAar explodeAar = null, List <string> repoPaths = null) { var currentDependencies = new Dictionary <string, KeyValuePair <Dependency, string> >(); if (dependencies.Count == 0) { return(currentDependencies); } // Copy the set of dependencies. var transitiveDependencies = new Dictionary <string, Dependency>(dependencies); // Expand set of transitive dependencies into the dictionary of dependencies. foreach (var rootDependency in dependencies.Values) { foreach (var transitiveDependency in GetDependencies(rootDependency, repoPaths)) { transitiveDependencies[transitiveDependency.Key] = transitiveDependency; } } // TODO(smiles): Need a callback that queries Unity's asset DB rather than touching // the filesystem here. string[] filesInDestDir = Directory.GetFileSystemEntries(destDirectory); foreach (var path in filesInDestDir) { // Ignore Unity's .meta files. if (path.EndsWith(MetaExtension)) { continue; } string filename = Path.GetFileName(path); // Strip the package extension from filenames. Directories generated from // unpacked AARs do not have extensions. bool pathIsDirectory = Directory.Exists(path); string filenameWithoutExtension = pathIsDirectory ? filename : Path.GetFileNameWithoutExtension(filename); foreach (var dep in transitiveDependencies.Values) { // Get the set of artifacts matching artifact-*. // The "-" is important to distinguish art-1.0.0 from artifact-1.0.0 // (or base- and basement-). var match = System.Text.RegularExpressions.Regex.Match( filenameWithoutExtension, String.Format("^{0}-.*", dep.Artifact)); if (match.Success) { // Extract the version from the filename. // dep.Artifact is the name of the package (prefix) // The regular expression extracts the version number from the filename // handling filenames like foo-1.2.3-alpha. match = System.Text.RegularExpressions.Regex.Match( filenameWithoutExtension.Substring( dep.Artifact.Length + 1), "^([0-9.]+)"); if (match.Success) { bool reportDependency = true; // If the AAR is exploded and it should not be, delete it and do not // report this dependency. if (pathIsDirectory && explodeAar != null) { string aarFile = dep.BestVersionArtifact; if (aarFile != null && !explodeAar(aarFile)) { DeleteExistingFileOrDirectory(path, includeMetaFiles: true); reportDependency = false; } } if (reportDependency) { string artifactVersion = match.Groups[1].Value; Dependency currentDep = new Dependency( dep.Group, dep.Artifact, artifactVersion, packageIds: dep.PackageIds, repositories: dep.Repositories); // Add the artifact version so BestVersion == Version. currentDep.AddVersion(currentDep.Version); currentDependencies[currentDep.Key] = new KeyValuePair <Dependency, string>(currentDep, path); } break; } } } } return(currentDependencies); }
internal Dependency FindCandidate(Dependency dep) { return(FindCandidate(dep, repositoryPaths)); }
/// <summary> /// Refines the possible version range based on the given candidate. /// This is done by removing possible versions that are not acceptable /// to the candidate. /// </summary> /// <returns><c>true</c>, if there are still possible versions.</returns> /// <param name="candidate">Candidate to test versions with.</param> public bool RefineVersionRange(Dependency candidate) { possibleVersions = FilterAcceptableVersions(candidate.Version, possibleVersions); return(HasPossibleVersions); }