public static SplitLines ( string multilineString ) : string[] | ||
multilineString | string | String to split into lines |
return | string[] |
public static string FindExecutable(string executable) { string text = (Application.platform != RuntimePlatform.WindowsEditor) ? "which" : "where"; try { CommandLine.Result result = CommandLine.Run(text, executable, Environment.CurrentDirectory, null, null); if (result.exitCode == 0) { return(CommandLine.SplitLines(result.stdout)[0]); } } catch (Exception ex) { UnityEngine.Debug.Log(string.Concat(new string[] { "'", text, "' command is not on path. Unable to find executable '", executable, "' (", ex.ToString(), ")" })); } return(null); }
/// <summary> /// Determine whether the user's JDK is sufficient for the Android SDK and recently /// released libraries. /// </summary> internal static void CheckJdkForApiLevel() { // Get JAVA_HOME path from the editor settings. string javaPath = null; try { javaPath = JavaBinaryPath; } catch (ToolNotFoundException) { return; } var result = CommandLine.Run(javaPath, "-version", Directory.GetCurrentDirectory(), envVars: new Dictionary <string, string> { { JAVA_HOME, JavaHome } }); if (result.exitCode != 0) { LogJdkVersionFailedWarning(javaPath, result.message); return; } float majorMinorVersion = 0; // The version string is can be reported via stderr or stdout so scrape the // concatenated message string. foreach (var line in CommandLine.SplitLines(result.message)) { if (line.StartsWith("java version ")) { var tokens = line.Split(); var versionString = tokens[tokens.Length - 1].Trim(new [] { '"' }); var components = versionString.Split(new [] { '.' }); if (components.Length < 2) { continue; } if (!float.TryParse(components[0] + "." + components[1], NumberStyles.Any, CultureInfo.InvariantCulture, out majorMinorVersion)) { continue; } } } if (majorMinorVersion == 0) { LogJdkVersionFailedWarning(javaPath, result.message); return; } // If the user's installed JDK is too old, report an error. if (majorMinorVersion < MINIMUM_JDK_VERSION_MAJOR_MINOR) { PlayServicesResolver.Log( String.Format("The configured JDK {0} is too old to build Android " + "applications with recent libraries.\n" + "Please install JDK version {1} or newer and configure Unity " + "to use the new JDK installation in the " + "'Unity Preferences > External Tools' menu.\n", majorMinorVersion, MINIMUM_JDK_VERSION_MAJOR_MINOR), level: LogLevel.Error); } }
/// <summary> /// Retrieve package licenses, display license dialog and then install packages. /// </summary> /// <param name="toolPath">Tool to run.</param> /// <param name="toolArguments">Arguments to pass to the tool.</param> /// <param name="packages">List of package versions to install / upgrade.</param> /// <param name="licenseQuestion">License question to respond to.</param> /// <param name="licenseAgree">String used to agree to a license.</param> /// <param name="licenseDecline">String used to decline a license.</param> /// <param name="licenseTextHeader">Regex which matches the line which is the start of a /// license agreement.</param> /// <param name="complete">Called when installation is complete.</param> public static void InstallPackages( string toolPath, string toolArguments, HashSet <AndroidSdkPackageNameVersion> packages, string licenseQuestion, string licenseAgree, string licenseDecline, Regex licenseTextHeader, Action <bool> complete) { PlayServicesResolver.Log(String.Format("Install Android SDK packages\n" + "\n" + "{0} {1}\n", toolPath, toolArguments), level: LogLevel.Verbose); // Display the license retrieval dialog. DisplayInstallLicenseDialog( toolPath, toolArguments, true, new LicenseResponder(licenseQuestion, licenseDecline), packages, (CommandLine.Result licensesResult) => { if (licensesResult.exitCode != 0) { complete(false); return; } // Get the license text. var licensesLines = new List <string>(); bool foundLicenses = false; foreach (var line in CommandLine.SplitLines(licensesResult.stdout)) { foundLicenses = foundLicenses || licenseTextHeader.Match(line).Success; if (foundLicenses) { licensesLines.Add(line); } } if (licensesLines.Count == 0) { LogInstallLicenseResult(toolPath, toolArguments, false, packages, licensesResult); complete(true); return; } // Display the license agreement dialog. DisplayLicensesDialog( String.Join("\n", licensesLines.ToArray()), (bool agreed) => { if (!agreed) { complete(false); return; } // Finally install the packages agreeing to the license questions. DisplayInstallLicenseDialog( toolPath, toolArguments, false, new LicenseResponder(licenseQuestion, licenseAgree), packages, (CommandLine.Result installResult) => { complete(installResult.exitCode == 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); }
/// <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); }
private void CommandLineIOHandler(Process process, StreamWriter stdin, CommandLine.StreamData data) { if (process.HasExited || data.data == null) { return; } if (data.handle == 0) { this.linesReported += this.CountLines(data.text); } string @string = Encoding.UTF8.GetString(data.data); this.textQueue.Enqueue(@string); string[] array = CommandLine.SplitLines(@string); for (int i = 0; i < array.Length; i++) { string message = array[i]; this.logger.Log(message, LogLevel.Verbose); } }
/// <summary> /// Called from RunCommandLine() tool to report the output of the currently /// executing commmand. /// </summary> /// <param name="process">Executing process.</param> /// <param name="stdin">Standard input stream.</param> /// <param name="data">Data read from the standard output or error streams.</param> private void CommandLineIOHandler(Process process, StreamWriter stdin, CommandLine.StreamData data) { if (process.HasExited || data.data == null) { return; } // Count lines in stdout. if (data.handle == 0) { linesReported += CountLines(data.text); } // Enqueue data for the text view. var newLines = System.Text.Encoding.UTF8.GetString(data.data); textQueue.Enqueue(newLines); // Write to the logger. foreach (var line in CommandLine.SplitLines(newLines)) { logger.Log(line, level: LogLevel.Verbose); } }
/// <summary> /// Parse "sdkmanager --list" output. /// </summary> /// <returns>Dictionary of packages bucketed by package name</returns> private AndroidSdkPackageCollection ParseListOutput( string sdkManagerListOutput) { 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; // Whether we're parsing the contents of the package table vs. the header. bool inPackageTable = false; foreach (var rawLine in CommandLine.SplitLines(sdkManagerListOutput)) { 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; inPackageTable = false; continue; } if (!parsingPackages) { continue; } if (!inPackageTable) { // If we've reached end of the table header, start parsing the set of packages. if (line.StartsWith("----")) { inPackageTable = true; } continue; } // Split into the fields package_name|version|description|location. // Where "location" is an optional field that contains the install path. var rawTokens = line.Split(new [] { '|' }); if (rawTokens.Length < 3 || String.IsNullOrEmpty(line)) { parsingPackages = false; continue; } // Each field is surrounded by whitespace so trim the fields. string[] tokens = new string[rawTokens.Length]; for (int i = 0; i < rawTokens.Length; ++i) { tokens[i] = rawTokens[i].Trim(); } var packageName = tokens[0]; packages[packageName].Add(new AndroidSdkPackage { Name = packageName, Description = tokens[2], VersionString = tokens[1], Installed = parsingInstalledPackages }); } return(packages); }
/// <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); }