예제 #1
0
        /// <summary>
        /// Initialize this instance.
        /// </summary>
        /// <param name="toolPath">Path of the android tool.</param>
        public SdkManager(string toolPath)
        {
            this.toolPath = toolPath;
            var toolsDir = Path.GetDirectoryName(Path.GetDirectoryName(toolPath));
            var sdkDir   = Path.GetDirectoryName(toolsDir);

            toolsPackage = AndroidSdkPackage.ReadFromSourceProperties(
                sdkDir, toolsDir.Substring((sdkDir + Path.PathSeparator).Length));
        }
예제 #2
0
        /// <summary>
        /// Parse "android list sdk -u -e -a" output.
        /// </summary>
        private AndroidSdkPackageCollection ParseAndroidListSdkOutput(
            string androidListSdkOutput)
        {
            var packages = new AndroidSdkPackageCollection();
            AndroidSdkPackage currentPackage = null;

            foreach (string line in CommandLine.SplitLines(androidListSdkOutput))
            {
                // Check for the start of a new package entry.
                if (line.StartsWith("---"))
                {
                    currentPackage = null;
                    continue;
                }
                Match match;
                // If this is the start of a package description, add a package.
                match = PACKAGE_ID_REGEX.Match(line);
                if (match.Success)
                {
                    // TODO(smiles): Convert the legacy package name to a new package name.
                    currentPackage = new AndroidSdkPackage {
                        LegacyName = match.Groups[1].Value
                    };
                    packages[currentPackage.Name].Add(currentPackage);
                    continue;
                }
                if (currentPackage == null)
                {
                    continue;
                }

                // Add a package description.
                match = PACKAGE_DESCRIPTION_REGEX.Match(line);
                if (match.Success)
                {
                    currentPackage.Description = match.Groups[1].Value;
                    continue;
                }
                // Parse the install path and record whether the package is installed.
                match = PACKAGE_INSTALL_LOCATION_REGEX.Match(line);
                if (match.Success)
                {
                    currentPackage.Installed = File.Exists(
                        Path.Combine(Path.Combine(sdkPath, match.Groups[1].Value),
                                     "source.properties"));
                }
            }
            return(packages);
        }
예제 #3
0
        /// <summary>
        /// Read package metadata from the source.properties file within the specified directory.
        /// </summary>
        /// <param name="sdkDirectory">Android SDK directory to query.</param>
        /// <param name="packageDirectory">Directory containing the package relative to
        /// sdkDirectory.</param>
        public static AndroidSdkPackage ReadFromSourceProperties(string sdkDirectory,
                                                                 string packageDirectory)
        {
            var propertiesPath = System.IO.Path.Combine(
                sdkDirectory, System.IO.Path.Combine(packageDirectory, "source.properties"));
            string propertiesText = null;

            try {
                propertiesText = File.ReadAllText(propertiesPath);
            } catch (Exception e) {
                PlayServicesResolver.Log(String.Format("Unable to read {0}\n{1}\n",
                                                       propertiesPath, e.ToString()),
                                         level: LogLevel.Verbose);
                return(null);
            }
            // Unfortunately the package name is simply based upon the path within the SDK.
            var sdkPackage = new AndroidSdkPackage {
                Path = packageDirectory
            };
            const string VERSION_FIELD_NAME     = "Pkg.Revision=";
            const string DESCRIPTION_FIELD_NAME = "Pkg.Desc=";

            foreach (var rawLine in CommandLine.SplitLines(propertiesText))
            {
                var line = rawLine.Trim();
                // Ignore comments.
                if (line.StartsWith("#"))
                {
                    continue;
                }
                // Parse fields
                if (line.StartsWith(VERSION_FIELD_NAME))
                {
                    sdkPackage.VersionString = line.Substring(VERSION_FIELD_NAME.Length);
                }
                else if (line.StartsWith(DESCRIPTION_FIELD_NAME))
                {
                    sdkPackage.Description = line.Substring(DESCRIPTION_FIELD_NAME.Length);
                }
            }
            return(sdkPackage);
        }
예제 #4
0
        /// <summary>
        /// Get the most recent available version of a specified package, prefering installed.
        /// </summary>
        /// <returns>The package if it's available, null otherwise.</returns>
        public AndroidSdkPackage GetMostRecentAvailablePackage(string packageName)
        {
            var list = this[packageName];

            if (list == null || !list.Any())
            {
                return(null);
            }
            var maxVersion = list.Max(p => p.Version);
            AndroidSdkPackage mostRecentPackage = null;

            foreach (var package in list)
            {
                if (package.Version == maxVersion && (mostRecentPackage == null || !mostRecentPackage.Installed))
                {
                    mostRecentPackage = package;
                }
            }
            return(mostRecentPackage);
        }
예제 #5
0
        /// <summary>
        /// Parse "sdkmanager --list --verbose" output.
        /// NOTE: The --verbose output format is only reported by sdkmanager 26.0.2 and above.
        /// </summary>
        private AndroidSdkPackageCollection ParseListVerboseOutput(
            string sdkManagerListVerboseOutput)
        {
            var packages = new AndroidSdkPackageCollection();
            // Whether we're parsing a set of packages.
            bool parsingPackages = false;
            // Whether we're parsing within the set of installed packages vs. available packages.
            bool parsingInstalledPackages = false;
            // Fields of the package being parsed.
            AndroidSdkPackage currentPackage = null;

            foreach (var rawLine in CommandLine.SplitLines(sdkManagerListVerboseOutput))
            {
                var line          = rawLine.Trim();
                var lowerCaseLine = line.ToLower();
                if (lowerCaseLine == AVAILABLE_UPDATES_HEADER)
                {
                    parsingPackages = false;
                    continue;
                }
                bool installedPackagesLine = lowerCaseLine == INSTALLED_PACKAGES_HEADER;
                bool availablePackagesLine = lowerCaseLine == AVAILABLE_PACKAGES_HEADER;
                if (installedPackagesLine || availablePackagesLine)
                {
                    parsingPackages          = true;
                    parsingInstalledPackages = installedPackagesLine;
                    continue;
                }
                else if (line.StartsWith("---"))
                {
                    // Ignore section separators.
                    continue;
                }
                else if (String.IsNullOrEmpty(line))
                {
                    if (currentPackage != null &&
                        !(String.IsNullOrEmpty(currentPackage.Name) ||
                          String.IsNullOrEmpty(currentPackage.VersionString)))
                    {
                        packages[currentPackage.Name].Add(currentPackage);
                    }
                    currentPackage = null;
                    continue;
                }
                else if (!parsingPackages)
                {
                    continue;
                }
                // Fields of the package are indented.
                bool indentedLine = rawLine.StartsWith("    ");
                if (!indentedLine)
                {
                    // If this isn't an indented line it should be a package name.
                    if (currentPackage == null)
                    {
                        currentPackage = new AndroidSdkPackage {
                            Name      = line,
                            Installed = parsingInstalledPackages
                        };
                    }
                }
                else if (currentPackage != null)
                {
                    // Parse the package field.
                    var fieldSeparatorIndex = line.IndexOf(":");
                    if (fieldSeparatorIndex >= 0)
                    {
                        var fieldName  = line.Substring(0, fieldSeparatorIndex).Trim().ToLower();
                        var fieldValue = line.Substring(fieldSeparatorIndex + 1).Trim();
                        if (fieldName == "description")
                        {
                            currentPackage.Description = fieldValue;
                        }
                        else if (fieldName == "version")
                        {
                            currentPackage.VersionString = fieldValue;
                        }
                    }
                }
            }
            return(packages);
        }