Beispiel #1
0
 public static void OnWillSaveAssets(string[] paths)
 {
     foreach (var asset in paths)
     {
         UTils.ClearUnusedEntriesIn(asset);
     }
 }
Beispiel #2
0
    /// <summary>
    /// Runs the specified plan.
    /// </summary>
    public static void Run(UTAutomationPlan plan, Dictionary <string, string> additionalProperties)
    {
        if (UTPreferences.ClearConsoleBeforeStart)
        {
            UTils.ClearConsole();
        }
        var context = new UTContext();

        if (additionalProperties != null)
        {
            foreach (var entry in additionalProperties)
            {
                string name = entry.Key;
                string val  = entry.Value;
                if (UTPreferences.DebugMode)
                {
                    Debug.Log("Setting additional property: " + name + " = " + val);
                }
                context[name] = val;
            }
        }

        UTMainWindow.Init();
        var runner = UTomateRunner.Instance;

        runner.RequestRun(plan, context);
    }
Beispiel #3
0
    /// <summary>
    /// Cleans up the entries in this statistics. This accounts for plans that have been deleted.
    /// </summary>
    public static void CleanUp()
    {
        var allPlans = UTils.AllVisibleAssetsOfType <UTAutomationPlan> ();

        var knownGuids = new HashSet <string> ();

        knownGuids.UnionWith(allPlans.ConvertAll(plan => plan.Guid));
        var       knownEntries = new List <StatEntry> ();
        var       i            = 0;
        StatEntry statEntry    = null;

        do
        {
            statEntry      = new StatEntry();
            statEntry.guid = EditorPrefs.GetString(PlanPrefix + i, "");
            if (!string.IsNullOrEmpty(statEntry.guid))
            {
                statEntry.project      = EditorPrefs.GetString(PlanPrefix + i + ".project", "");
                statEntry.lastModified = FromString(EditorPrefs.GetString(PlanPrefix + i + ".lastModified"));
                statEntry.time         = EditorPrefs.GetFloat(PlanPrefix + i + ".time", 0f);

                if (knownGuids.Contains(statEntry.guid))
                {
                    knownEntries.Add(statEntry);
                }
                else
                {
                    // not known, check if it's from this project
                    if (statEntry.project != Application.dataPath)
                    {
                        // different project, candidate for keeping it
                        var age = DateTime.Now - statEntry.lastModified;
                        if (age.TotalDays < 90)
                        {
                            // age is recent, keep it.
                            knownEntries.Add(statEntry);
                        }
                    }
                    // in all other cases, kill it.
                }


                EditorPrefs.DeleteKey(PlanPrefix + i);
                EditorPrefs.DeleteKey(PlanPrefix + i + ".time");
                EditorPrefs.DeleteKey(PlanPrefix + i + ".project");
                EditorPrefs.DeleteKey(PlanPrefix + i + ".lastModified");
            }
            i++;
        } while (!string.IsNullOrEmpty(statEntry.guid));

        i = 0;
        foreach (var entry in knownEntries)
        {
            EditorPrefs.SetString(PlanPrefix + i, entry.guid);
            EditorPrefs.SetFloat(PlanPrefix + i + ".time", entry.time);
            EditorPrefs.SetString(PlanPrefix + i + ".project", entry.project);
            EditorPrefs.SetString(PlanPrefix + i + ".lastModified", ToString(entry.lastModified));
            i++;
        }
    }
Beispiel #4
0
    /// <summary>
    /// Adds an arbitrary entry at the given position.
    /// </summary>
    /// <returns>
    /// The entry that was added.
    /// </returns>
    /// <param name='position'>
    /// Position at which the entry should be added.
    /// </param>
    /// <typeparam name='T'>
    /// The type of the entry to be added.
    /// </typeparam>
    public T AddEntry <T> (Vector2 position) where T : UTAutomationPlanEntry
    {
        CUUndoUtility.RegisterUndo(new UObject[] { data, graphData }, "Add Node");
        var entry = UTils.AddAssetOfType <T> (PlanPath, true);

        entry.automationPlanEntryId = Guid.NewGuid().ToString();
        if (data.firstEntry == null)
        {
            data.firstEntry = entry;
        }

        UTNode node = new UTNode();

        node.Data   = entry;
        node.Bounds = new Rect(position.x, position.y, 200, 200);
        graphData.AddNode(node);

        // add offset for next node
        position.x += 50;
        position.y += 50;
        EditorUtility.SetDirty(entry);
        EditorUtility.SetDirty(graphData);
        SelectNode(node, SelectionMode.Replace);
        return(entry);
    }
    public static void CreateEcosystemPlan()
    {
        // get the folder selection

        // create a new plan at the currently selected folder.
        UTAutomationPlan plan = UTils.CreateAssetOfType <UTAutomationPlan>("name");

        // create a new instance of the new class we created above.
        var editorModel = new PlayMakerEcosystem_uTomateModel();

        editorModel.LoadPlan(plan);

        Selection.activeInstanceID = plan.GetInstanceID();

        // now you can create actions.

        // FIRST ACTION
        UTEchoAction echoAction = UTAction.Create <UTEchoAction>();

        // set their properties
        echoAction.text.Value         = "Hello World";
        echoAction.text.UseExpression = false; // this toggles f(x)

        // add the action to the automation plan
        var echoActionEntry = editorModel.AddAction(echoAction);

        echoActionEntry.name = "wtf";

        Selection.activeInstanceID = plan.GetInstanceID();

        // SECOND ACTION
        UTEchoAction anotherAction = UTAction.Create <UTEchoAction>();


        // set their properties
        anotherAction.text.Value         = "double dva";
        anotherAction.text.UseExpression = false; // this toggles f(x)

        // add it as well
        var anotherActionEntry = editorModel.AddAction(anotherAction);


        //CONNECT
        // now connect the first echo action to the other action using the Connect method we wrote
        editorModel.Connect(echoActionEntry, anotherActionEntry);

        // finally set the echo action as first action
        var echoActionNode = editorModel.Graph.GetNodeFor(echoActionEntry);

        editorModel.SetFirstNode(echoActionNode);


        // if you want you can beautify the graph
        // so not all nodes are located at (0,0)
        editorModel.RelayoutPlan();

        // finally you can execute your plan using
        UTomate.Run(plan);
    }
Beispiel #6
0
    /// <summary>
    /// Creates a new UBuildAction of the given type.
    /// </summary>
    /// <typeparam name='T'>
    /// The type of action to create.
    /// </typeparam>
    public static T Create <T>() where T : UTAction
    {
        UTDoc doc    = UTDoc.GetFor(typeof(T));
        var   result = UTils.CreateAssetOfType <T>(doc.title);

        result.CreatedWithActionVersion = ActionVersion;
        return(result);
    }
Beispiel #7
0
    public static void Create()
    {
#if UTOMATE_DEMO
        if (UTomate.CheckPlanCountExceeded())
        {
            return;
        }
#endif
        UTils.CreateAssetOfType <UTAutomationPlan> ("Automation Plan");
    }
    private static bool HasRequiredLicense(AttributeLookup attributeLookup, out string message)
    {
        var requiredComponents = new List <String> ();
        var licenseAttribute   = GetAttribute <UTRequiresLicenseAttribute> (attributeLookup);

        if (licenseAttribute != null)
        {
            var theLicense = licenseAttribute.license;
            if ((theLicense & UTLicense.UnityPro) != 0 && !UTils.IsUnityPro)
            {
                requiredComponents.Add("Unity Pro");
            }
            if ((theLicense & UTLicense.IosPro) != 0 && !UTils.HasAdvancedLicenseOn(UnityEditor.BuildTarget.iOS))
            {
                requiredComponents.Add("iOS Pro");
            }
            if ((theLicense & UTLicense.AndroidPro) != 0 && !UTils.HasAdvancedLicenseOn(UnityEditor.BuildTarget.Android))
            {
                requiredComponents.Add("Android Pro");
            }
        }
        else
        {
            // legacy attributes support, this will be removed later.
#pragma warning disable 618
            var unityProAttribute = GetAttribute <UTRequiresUnityPro> (attributeLookup);
            if (unityProAttribute != null && !UTils.IsUnityPro)
            {
                requiredComponents.Add("Unity Pro");
            }

            var unityIosAttribute = GetAttribute <UTRequiresiOS> (attributeLookup);
            if (unityIosAttribute != null && unityIosAttribute.iOSPro && !UTils.HasAdvancedLicenseOn(UnityEditor.BuildTarget.iOS))
            {
                requiredComponents.Add("iOS Pro");
            }


            var unityAndroidAttribute = GetAttribute <UTRequiresAndroid> (attributeLookup);
            if (unityAndroidAttribute != null && unityAndroidAttribute.androidPro && !UTils.HasAdvancedLicenseOn(UnityEditor.BuildTarget.Android))
            {
                requiredComponents.Add("Android Pro");
            }
#pragma warning restore 618
        }

        if (requiredComponents.Count > 0)
        {
            message = String.Join(", ", requiredComponents.ToArray());
            return(false);
        }
        message = "";
        return(true);
    }
Beispiel #9
0
    private void CleanUp()
    {
        UTils.ClearAsyncProgressBar();
        var cancelled = context.CancelRequested;
        var failed    = context.Failed;

        context    = null;
        enumerator = null;

        var endTime  = DateTime.Now;
        var duration = endTime - startTime;

        if (!cancelled && !failed)           // recording cancelled runs will greatly diminish the accuracy of the statistics, so don't record them
        {
            UTStatistics.RecordRuntime(plan, (float)duration.TotalSeconds);
        }
        plan = null;
        Debug.Log("Automation finished in " + FormatTime(duration, false) + ".");
        if (cancelled)
        {
            Debug.LogWarning("Run was canceled by user.");
        }
        if (failed)
        {
            Debug.LogError("Run failed with error.");
        }

        if (OnRunnerFinished != null)
        {
            OnRunnerFinished(cancelled, failed);
        }

        // now check if the player settings were modified by an action, in this case we don't reset them
        var newBackgroundSetting = PlayerSettings.runInBackground;

        Application.runInBackground = false;

        // and reset it back if it wasn't so we don't f**k up what was set before..
        if (newBackgroundSetting == playerSettingsRunInBackgroundValue)
        {
            // not modified by an action, in this case reset it
            PlayerSettings.runInBackground = playerSettingsRunInBackgroundValue;
        }

        if (reloadOfAssembliesLocked)
        {
            Debug.Log("Releasing assembly reload lock now.");
            EditorApplication.UnlockReloadAssemblies();
        }
        AssetDatabase.Refresh();          // make sure updates are shown in the editor.
    }
    private void SetupVariables(UTContext context)
    {
        context ["project:root"]   = UTFileUtils.ProjectRoot;
        context ["project:assets"] = UTFileUtils.ProjectAssets;

        var platform = Environment.OSVersion.Platform;

        if (Application.platform == RuntimePlatform.OSXEditor)
        {
            platform = PlatformID.MacOSX;             // seems to be some bug in Mono returning "Unix" when being on a mac.
        }

        context ["os:platform"] = platform.ToString();

        var isUnixLike = platform == PlatformID.MacOSX || platform == PlatformID.Unix;

        context ["os:pathSeparatorType"] = isUnixLike ? "Unix" : "Windows";
        context ["os:pathSeparatorChar"] = isUnixLike ? "/" : "\\";

        if (isUnixLike)
        {
            context ["user:home"] = UTFileUtils.NormalizeSlashes(Environment.GetEnvironmentVariable("HOME"));
        }
        else if (platform == PlatformID.Win32NT)
        {
            context ["user:home"] = UTFileUtils.NormalizeSlashes(Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%"));
        }
        else
        {
            Debug.Log("Unable to detect underlying os. Property 'user:home' is not available.");
        }

        context ["user:desktop"] = UTFileUtils.NormalizeSlashes(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));

        context ["unity:isUnityPro"]      = UTils.IsUnityPro;
        context ["unity:supportsAndroid"] = UTils.IsBuildTargetSupported(UnityEditor.BuildTarget.Android);
        context ["unity:supportsIos"]     = UTils.IsBuildTargetSupported(UnityEditor.BuildTarget.iOS);
        context ["unity:version"]         = Application.unityVersion;

        context ["utomate:debugMode"] = UTPreferences.DebugMode;

        context ["project:picard"] = "Make it so!";
        context ["project:worf"]   = "Torpedos ready, sir!";
        context ["project:bones"]  = "I'm a doctor, no game developer!";
    }
Beispiel #11
0
    /// <summary>
    /// Loads a plan into this model.
    /// </summary>
    /// <param name='plan'>
    /// The plan to load.
    /// </param>
    public void LoadPlan(UTAutomationPlan plan)
    {
        if (plan != null)
        {
            data = plan;
            string path = PlanPath;
            graphData = null;
            selectedNodes.Clear();

            // objects with hide fagl are not returned by LoadAssetAtPath
            UnityEngine.Object[] assets = AssetDatabase.LoadAllAssetsAtPath(path);
            foreach (UnityEngine.Object asset in assets)
            {
                if (asset is UTGraph)
                {
                    graphData = (UTGraph)asset;
                    break;
                }
            }
            if (graphData == null)
            {
                graphData      = UTils.AddAssetOfType <UTGraph> (path, true);
                graphData.name = "Graph";
                EditorUtility.SetDirty(graphData);
            }
            if (plan.firstEntry != null)
            {
                SelectNode(graphData.GetNodeFor(plan.firstEntry), SelectionMode.Add);
            }
        }
        else
        {
            data      = null;
            graphData = null;
            selectedNodes.Clear();
            highlightedNode = null;
        }
    }
Beispiel #12
0
 public static List <UTAutomationPlan> AllUTAutomationPlans()
 {
     return(UTils.AllVisibleAssetsOfType <UTAutomationPlan> ());
 }
 public static void Create()
 {
     UTils.CreateAssetOfType <ChangeLog> ("Change Log");
 }
Beispiel #14
0
    public override System.Collections.IEnumerator Execute(UTContext context)
    {
        if (EditorUserBuildSettings.activeBuildTarget == BuildTarget.WebPlayer ||
            EditorUserBuildSettings.activeBuildTarget == BuildTarget.WebPlayerStreamed)
        {
            Debug.LogWarning("You have currently set the build target to 'Web Player'. This may cause interference with actions that access the internet. If you get an error message about cross domain policy from this action, switch the target to 'PC and Mac Standalone' and try again.");
        }

        var theNexusUrl = nexusUrl.EvaluateIn(context);

        if (string.IsNullOrEmpty(theNexusUrl))
        {
            throw new UTFailBuildException("You need to specify the nexus URL", this);
        }

        var theRepoId = repositoryId.EvaluateIn(context);

        if (string.IsNullOrEmpty(theRepoId))
        {
            throw new UTFailBuildException("You need to specify the repository id.", this);
        }


        var theUserName = userName.EvaluateIn(context);
        var thePassword = password.EvaluateIn(context);

        var theGroupId = groupId.EvaluateIn(context);

        if (string.IsNullOrEmpty(theGroupId))
        {
            throw new UTFailBuildException("You need to specify the group id.", this);
        }

        var theArtifactId = artifactId.EvaluateIn(context);

        if (string.IsNullOrEmpty(theArtifactId))
        {
            throw new UTFailBuildException("You need to specify the artifact id.", this);
        }

        var theVersion = version.EvaluateIn(context);

        if (string.IsNullOrEmpty(theVersion))
        {
            throw new UTFailBuildException("You need to specify the version.", this);
        }


        var thePackaging = packaging.EvaluateIn(context);

        if (string.IsNullOrEmpty(thePackaging))
        {
            throw new UTFailBuildException("You need to specify the packaging.", this);
        }

        var theExtension  = extension.EvaluateIn(context);
        var theClassifier = classifier.EvaluateIn(context);

        var theInputFileName = inputFileName.EvaluateIn(context);

        if (string.IsNullOrEmpty(theInputFileName))
        {
            throw new UTFailBuildException("You need to specify the input file name.", this);
        }

        if (Directory.Exists(theInputFileName))
        {
            throw new UTFailBuildException("The specified input file " + theInputFileName + " is a directory.", this);
        }

        if (!File.Exists(theInputFileName))
        {
            throw new UTFailBuildException("The specified input file " + theInputFileName + " does not exist.", this);
        }

        WWWForm form = new WWWForm();

        form.AddField("r", theRepoId);
        form.AddField("g", theGroupId);
        form.AddField("a", theArtifactId);
        form.AddField("v", theVersion);

        if (!string.IsNullOrEmpty(thePackaging))
        {
            form.AddField("p", thePackaging);
        }

        if (!string.IsNullOrEmpty(theClassifier))
        {
            form.AddField("c", theClassifier);
        }

        if (!string.IsNullOrEmpty(theExtension))
        {
            form.AddField("e", theExtension);
        }

        var bytes = File.ReadAllBytes(theInputFileName);

        form.AddBinaryData("file", bytes, new FileInfo(theInputFileName).Name);

        var hash = UTils.ComputeHash(bytes);

        if (UTPreferences.DebugMode)
        {
            Debug.Log("SHA1-Hash of file to upload: " + hash);
        }

        string authString = theUserName + ":" + thePassword;
        var    authBytes  = System.Text.UTF8Encoding.UTF8.GetBytes(authString);

        var headers = new Hashtable();

        foreach (var key in form.headers.Keys)
        {
            headers.Add(key, form.headers [key]);
        }

        headers.Add("Authorization", "Basic " + System.Convert.ToBase64String(authBytes));
        var url = UTils.BuildUrl(theNexusUrl, "/service/local/artifact/maven/content");

//		using (var www = new WWW (url, form.data,
//#if UNITY_WP8
//            PortUtil.HashtableToDictionary<string, string>(headers)
//#else
//            headers
//#endif
//            ))
//        {
//			do {
//				yield return "";
//			} while(!www.isDone && !context.CancelRequested);


//			if (UTPreferences.DebugMode) {
//				Debug.Log ("Server Response: " + www.text);
//			}
//		}

        if (!context.CancelRequested)
        {
            using (var wc = new WebClient()) {
                if (!string.IsNullOrEmpty(theUserName))
                {
                    Debug.Log("Setting credentials");
                    wc.Credentials = new NetworkCredential(theUserName, thePassword);
                }


                Uri uri = new Uri(UTils.BuildUrl(theNexusUrl, "/service/local/artifact/maven/resolve?") +
                                  "g=" + Uri.EscapeUriString(theGroupId) +
                                  "&a=" + Uri.EscapeUriString(theArtifactId) +
                                  "&v=" + Uri.EscapeUriString(theVersion) +
                                  "&r=" + Uri.EscapeUriString(theRepoId) +
                                  "&p=" + Uri.EscapeUriString(thePackaging) +
                                  (!string.IsNullOrEmpty(theClassifier) ? "&c=" + Uri.EscapeUriString(theClassifier) : "") +
                                  (!string.IsNullOrEmpty(theExtension) ? "&e=" + Uri.EscapeUriString(theExtension) : ""));


                var    downloadFinished = false;
                var    error            = false;
                string result           = null;
                wc.DownloadStringCompleted += delegate(object sender, DownloadStringCompletedEventArgs e) {
                    downloadFinished = true;
                    error            = e.Error != null;
                    if (error)
                    {
                        Debug.LogError("An error occured while downloading artifact information. " + e.Error.Message, this);
                    }
                    else
                    {
                        result = (string)e.Result;
                    }
                };

                wc.DownloadStringAsync(uri);

                do
                {
                    yield return("");

                    if (context.CancelRequested)
                    {
                        wc.CancelAsync();
                    }
                } while(!downloadFinished);

                if (!context.CancelRequested)
                {
                    if (!error)
                    {
                        if (UTPreferences.DebugMode)
                        {
                            Debug.Log("Server Response: " + result);
                        }
                        if (result.Contains("<sha1>" + hash + "</sha1>"))
                        {
                            Debug.Log("Successfully uploaded artifact " + theInputFileName + ".", this);
                        }
                        else
                        {
                            throw new UTFailBuildException("Upload failed. Checksums do not match.", this);
                        }
                    }
                    else
                    {
                        throw new UTFailBuildException("Artifact verification failed", this);
                    }
                }
            }
        }
    }
Beispiel #15
0
    public override IEnumerator Execute(UTContext context)
    {
        var theProjectPath = projectPath.EvaluateIn(context);

        if (!Directory.Exists(theProjectPath))
        {
            throw new UTFailBuildException("Project path " + theProjectPath + " does not exist.", this);
        }


        if (UTFileUtils.IsBelow(UTFileUtils.ProjectRoot, theProjectPath))
        {
            throw new UTFailBuildException("You cannot run uTomate externally on the current project. Use the Sub-Plan node if you want to run a plan as part of a plan.", this);
        }

        var thePlanName  = planName.EvaluateIn(context);
        var theDebugMode = debugMode.EvaluateIn(context);

        var theProperties = EvaluateAll(properties, context);

        StringBuilder sb = new StringBuilder();

        foreach (var prop in theProperties)
        {
            sb.Append(" -prop ").Append(UTExecutableParam.Quote(prop));
        }

        Process process = new Process();

        process.StartInfo.FileName  = UTils.GetEditorExecutable();
        process.StartInfo.Arguments = "-projectPath " + UTExecutableParam.Quote(theProjectPath) +
                                      " -executeMethod UTExternalRunner.RunPlan -plan " + UTExecutableParam.Quote(thePlanName) +
                                      " -debugMode " + theDebugMode + sb.ToString();
        if (UTPreferences.DebugMode)
        {
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.UseShellExecute        = false;
            process.OutputDataReceived += (sender, args) => UDebug.Log("[Unity]" + args.Data);
            UDebug.Log("Executing: " + process.StartInfo.FileName + " with arguments " + process.StartInfo.Arguments);
        }

        try {
            if (!process.Start())
            {
                throw new UTFailBuildException("Unable to start Unity3D.", this);
            }
            if (UTPreferences.DebugMode)
            {
                process.BeginOutputReadLine();
            }
        } catch (Win32Exception e) {
            throw new UTFailBuildException("Unable to start process " + e.Message, this);
        }
        do
        {
            yield return("");

            if (context.CancelRequested && !process.HasExited)
            {
                process.Kill();
                break;
            }
        } while(!process.HasExited);

        if (!context.CancelRequested && failOnError.EvaluateIn(context))
        {
            if (process.ExitCode != 0)
            {
                throw new UTFailBuildException("Plan " + thePlanName + " failed or was cancelled.", this);
            }
        }
    }