Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
Size: Mime:
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Fluctio.FluctioSim.Common.Configuration;
using Fluctio.FluctioSim.EditorUtils.EditorGeneral;
using Fluctio.FluctioSim.EditorUtils.OperatingSystem;
using JetBrains.Annotations;
using UnityEditor;

namespace Fluctio.FluctioSim.EditorCore.Training.PythonWrappers
{
	public static class PythonFinder
	{
		// TODO: update info when outdated to prevent showing "ok" when user uninstalled python
		
		public static readonly Regex PythonNameRegex = new(@"^py(thon)?(3(\.\d+)*)?(\.exe)?$");
		
		[CanBeNull]
		public static string Path
		{
			get
			{
				var path = SessionState.GetString("PythonPath", "");
				return path != "" ? path : null;
			}
			private set => SessionState.SetString("PythonPath", value ?? "");
		}
		
		[CanBeNull]
		public static Version Version
		{
			get
			{
				var versionString = SessionState.GetString("PythonVersion", "");
				var isSuccess = Version.TryParse(versionString, out var version);
				return isSuccess ? version : null;
			}
			private set => SessionState.SetString("PythonVersion", value?.ToString() ?? "");
		}
		
		public static bool IsInstalled => Path != null;
		public static bool IsSupportedVersion => Version != null && Config.IsPythonVersionSupported(Version);

		private static Task _pythonSearchingTask;
		public static bool IsSearching => _pythonSearchingTask is { IsCompleted: false };

		[InitializeOnLoadMethod]
		private static void Init()
		{
			if (!EditorUtil.DidEditorJustOpen)
			{
				return;
			}
			TryFindPython();
		}

		[ItemCanBeNull]
		private static async Task<Version> TryGetVersion(string commandToTry)
		{
			string commandResult;
			try
			{
				commandResult = await ProcessUtil.RunAndGet($"{commandToTry} --version");
			}
			catch (ProcessRuntimeException)
			{
				return null;
			}

			if (!commandResult.StartsWith("Python "))
			{
				return null;
			}
			var versionString = commandResult.Split(" ", 3)[1];
			var isSuccess = Version.TryParse(versionString, out var version);
			return isSuccess ? version : null;
		}

		// TODO: ability to set custom value in settings
		public static Task TryFindPython()
		{
			// TODO: run commands in parallel?
			var pythonPaths =
				from directoryPath in Platform.EnvironmentPath
				let directiry = new DirectoryInfo(directoryPath)
				where directiry.Exists
				let files = directiry.EnumerateFiles()
				from file in files
				where PythonNameRegex.IsMatch(file.Name)
				select file.FullName;
			
			var progress = new UnityProgress(
				"Find Python installation",
				"Looking for python...",
				async progress =>
				{
					string newPath = null;
					Version newVersion = null;
					foreach (var pythonPath in pythonPaths)
					{
						progress.StepStarted(pythonPath);
						var version = await TryGetVersion(pythonPath);
						if (version == null)
						{
							continue;
						}
						newPath = pythonPath;
						newVersion = version;
						if (Config.IsPythonVersionSupported(newVersion))
						{
							break;
						}
					}
					Path = newPath;
					Version = newVersion;
				});
			progress.InitSteps(pythonPaths.Count());
			_pythonSearchingTask = progress.RunAsync();
			return _pythonSearchingTask;
		}
	}
}