Пример #1
0
 public static Process RunNoWait(string executable, string arguments, ShellProcessArgs processArgs, DataReceivedEventHandler outputReceived = null, DataReceivedEventHandler errorReceived = null)
 {
     try
     {
         var exeDir = Where(executable, processArgs.ExtraPaths);
         if (exeDir == null)
         {
             if (processArgs.ThrowOnError)
             {
                 throw new FileNotFoundException($"Could not find command '{executable}' in the given search locations.");
             }
             return(null);
         }
         return(StartProcess(Path.Combine(exeDir.FullName, executable), arguments, processArgs.WorkingDirectory, outputReceived, errorReceived));
     }
     catch (Exception e)
     {
         TinyEditorAnalytics.SendException("Shell.RunNoWait", e);
         throw;
     }
 }
Пример #2
0
        public static ShellProcessOutput RunInShell(string command, ShellProcessArgs args)
        {
            Assert.IsFalse(string.IsNullOrEmpty(command));
            Assert.IsNotNull(args);

            try
            {
                var extraPaths       = args.ExtraPaths;
                var workingDirectory = args.WorkingDirectory;
                var throwOnError     = args.ThrowOnError;

                var runOutput = new ShellProcessOutput();

                var hasErrors   = false;
                var output      = new StringBuilder();
                var logOutput   = new StringBuilder();
                var errorOutput = new StringBuilder();

                // Setup shell command
                if (extraPaths != null)
                {
                    var sb = new StringBuilder(128);
                    foreach (var part in extraPaths)
                    {
                        if (string.IsNullOrEmpty(part))
                        {
                            continue;
                        }

                        if (sb.Length > 0)
                        {
                            sb.Append(s_PathSeparator);
                        }

#if UNITY_EDITOR_WIN
                        sb.Append(part.Trim('"'));
#else
                        sb.Append(part[0] == '"' ? part : part.DoubleQuoted());
#endif
                    }

#if UNITY_EDITOR_WIN
                    command = $"SET PATH={sb}{s_PathSeparator}%PATH%{Environment.NewLine}{command}";
#else
                    command = $"export PATH={sb}{s_PathSeparator}$PATH{Environment.NewLine}{command}";
#endif
                }

                LogProcessData($"TINY SHELL> {(workingDirectory?.FullName ?? new DirectoryInfo(".").FullName)}",
                               logOutput);
                LogProcessData(command, logOutput);

                // Setup temporary command file
                var tmpCommandFile = Path.GetTempPath() + Guid.NewGuid().ToString();
#if UNITY_EDITOR_WIN
                tmpCommandFile += ".bat";
#else
                tmpCommandFile += ".sh";
#endif
                File.WriteAllText(tmpCommandFile, command);

                // Prepare data received handlers
                DataReceivedEventHandler outputReceived = (sender, e) =>
                {
                    LogProcessData(e.Data, output);
                    logOutput.Append(e.Data);
                };
                DataReceivedEventHandler errorReceived = (sender, e) =>
                {
                    LogProcessData(e.Data, output);
                    errorOutput.Append(e.Data);
                    logOutput.Append(e.Data);
                    if (!string.IsNullOrEmpty(e.Data))
                    {
                        hasErrors = true;
                    }
                };

                // Run command in shell and wait for exit
                try
                {
#if UNITY_EDITOR_WIN
                    using (var process = StartProcess("cmd.exe", $"/Q /C \"{tmpCommandFile}\"", workingDirectory, outputReceived, errorReceived))
#else
                    using (var process = StartProcess("bash", $"\"{tmpCommandFile}\"", workingDirectory, outputReceived,
                                                      errorReceived))
#endif
                    {
                        var exitCode = WaitForProcess(process, output, args.MaxIdleTimeInMilliseconds);
                        runOutput.ExitCode      = exitCode;
                        runOutput.Command       = command;
                        runOutput.CommandOutput = output.ToString();
                        runOutput.FullOutput    = logOutput.ToString();
                        runOutput.ErrorOutput   = errorOutput.ToString();
                        LogProcessData($"Process exited with code '{exitCode}'", logOutput);
                        hasErrors |= (exitCode != 0);
                    }
                }
                finally
                {
                    File.Delete(tmpCommandFile);
                }

                if (hasErrors && throwOnError)
                {
                    throw new Exception($"{UTinyConstants.ApplicationName}: " + errorOutput.ToString());
                }

                runOutput.Succeeded = !hasErrors;

                return(runOutput);
            }
            catch (Exception e)
            {
                TinyEditorAnalytics.SendException("Shell.RunInShell", e);
                throw;
            }
        }
        public static UTinyBuildResults Build(UTinyBuildOptions options)
        {
            if (options?.Project == null || options.Destination == null)
            {
                throw new ArgumentException($"{UTinyConstants.ApplicationName}: invalid build options provided", nameof(options));
            }

            var buildStart = DateTime.Now;

            var           results = new UTinyBuildResults();
            IUTinyBuilder builder = null;

            switch (options.Platform)
            {
            case UTinyPlatform.HTML5:
                builder = new UTinyHTML5Builder();
                break;

            default:
                throw new ArgumentException($"{UTinyConstants.ApplicationName}: build platform not supported", nameof(options));
            }

            try
            {
                EditorUtility.DisplayProgressBar(ProgressBarTitle, "Build started for " + options.Platform.ToString(),
                                                 0.0f);

                var destFolder = options.Destination;
                destFolder.Create();

                // BUILD = <DEST>/PLATFORM/CONFIG
                var buildFolder = new DirectoryInfo(GetBuildDirectory(options.Project, options.Platform, options.Configuration));

                results.OutputFolder = buildFolder;

                UTinyBuildUtilities.PurgeDirectory(buildFolder);
                buildFolder.Create();

                options.Destination = results.BinaryFolder = buildFolder;

                var idlFile = new FileInfo(Path.Combine(buildFolder.FullName, "generated.cs"));
                UTinyIDLGenerator.GenerateIDL(options.Project, idlFile);

                var distFolder = GetRuntimeDistFolder();

                var bindGem = new FileInfo(Path.Combine(
                                               distFolder.FullName, "bindgem/BindGem/bin/Release/BindGem.exe"));

                var exeName = "\"" + bindGem.FullName + "\"";

                // always call bindgem with mono for consistency
                exeName = "mono " + exeName;

                // reference the core runtime file
                var bindReferences = $"-r \"{RuntimeDefsAssemblyPath}\"";

                UTinyBuildUtilities.RunInShell(
                    $"{exeName} -j {bindReferences} -o bind-generated {idlFile.Name}",
                    new ShellProcessArgs()
                {
                    WorkingDirectory = buildFolder,
                    ExtraPaths       = TinyPreferences.MonoDirectory.AsEnumerable()
                });

                // @TODO Perform a full refresh before building

                builder.Build(options, results);

                results.BuildReport.Update();

                Debug.Log($"{UTinyConstants.ApplicationName} project generated at: {results.BinaryFolder.FullName}");

                TinyEditorAnalytics.SendBuildEvent(options.Project, results, DateTime.Now - buildStart);
                return(results);
            }
            catch (Exception ex)
            {
                TinyEditorAnalytics.SendException("BuildPipeline.Build", ex);
                throw;
            }
            finally
            {
                EditorUtility.ClearProgressBar();
                UTinyEditorUtility.RepaintAllWindows();
            }
        }