예제 #1
0
        /// <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);
        }
예제 #2
0
 internal IEnumerable <Dependency> GetDependencies(Dependency dep)
 {
     return(GetDependencies(dep, repositoryPaths));
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
 internal Dependency FindCandidate(Dependency dep)
 {
     return(FindCandidate(dep, repositoryPaths));
 }
예제 #5
0
 /// <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);
 }