LogError() public static method

public static LogError ( this task, string message, string file = null ) : void
task this
message string
file string
return void
        public override bool Execute()
        {
            logger = new BuildLogger(BuildEngine);
            logger.LogInfo($"ScriptBuilderTask (version {typeof(ScriptBuilderTask).Assembly.GetName().Version}) Executing");

            var stopwatch = Stopwatch.StartNew();

            try
            {
                if (!ValidateInputs())
                {
                    return false;
                }
                Inner();
            }
            catch (ErrorsException exception)
            {
                logger.LogError(exception.Message, exception.FileName);
            }
            catch (Exception exception)
            {
                logger.LogError(exception.ToFriendlyString());
            }
            finally
            {
                logger.LogInfo($"  Finished ScriptBuilderTask {stopwatch.ElapsedMilliseconds}ms.");
            }
            return !logger.ErrorOccurred;
        }
        public override bool Execute()
        {
            logger = new BuildLogger(BuildEngine);
            logger.LogInfo($"SqlPersistenceScriptBuilderTask (version {assemblyVersion}) Executing");

            var stopwatch = Stopwatch.StartNew();

            try
            {
                ValidateInputs();
                var innerTask = new InnerTask(AssemblyPath, IntermediateDirectory, ProjectDirectory, SolutionDirectory,
                                              logError: (error, file) =>
                {
                    logger.LogError(error, file);
                });
                innerTask.Execute();
            }
            catch (ErrorsException exception)
            {
                logger.LogError(exception.Message, exception.FileName);
            }
            catch (Exception exception)
            {
                logger.LogError(exception.ToFriendlyString());
            }
            finally
            {
                logger.LogInfo($"  Finished SqlPersistenceScriptBuilderTask {stopwatch.ElapsedMilliseconds}ms.");
            }
            return(!logger.ErrorOccurred);
        }
Esempio n. 3
0
        public bool Convert(BuildInput.AddressableAsset[] input, out BuildInput output, bool useCache = true)
        {
            // If enabled, try loading from cache
            var hash = CalculateInputHash(input);

            if (useCache && LoadFromCache(hash, out output))
            {
                return(true);
            }

            // Convert inputs
            output = new BuildInput();

            if (input.IsNullOrEmpty())
            {
                BuildLogger.LogError("Unable to continue packing. Input is null or empty!");
                return(false);
            }

            output.definitions = new BuildInput.Definition[input.Length];
            for (var index = 0; index < input.Length; index++)
            {
                output.definitions[index].assetBundleName = input[index].asset.ToString();
                output.definitions[index].explicitAssets  = new[] { input[index] };
            }

            // Cache results
            if (useCache)
            {
                SaveToCache(hash, output);
            }
            return(true);
        }
Esempio n. 4
0
    public bool Execute()
    {
        var executingMessage = string.Format("Fody (version {0}) Executing", typeof (Processor).Assembly.GetName().Version);
        BuildEngine.LogMessageEvent(new BuildMessageEventArgs(executingMessage, "", "Fody", MSMessageEnum.High));

        var stopwatch = Stopwatch.StartNew();

        Logger = new BuildLogger(MessageImportance)
                     {
                         BuildEngine = BuildEngine,
                     };

        try
        {
            Inner();
            return !Logger.ErrorOccurred;
        }
        catch (Exception exception)
        {
            Logger.LogError(exception.ToFriendlyString());
            return false;
        }
        finally
        {
            var finishedMessage = string.Format("\tFinished Fody {0}ms.", stopwatch.ElapsedMilliseconds);
            Logger.Flush();
            BuildEngine.LogMessageEvent(new BuildMessageEventArgs(finishedMessage, "", "Fody", MSMessageEnum.High));
        }
    }
Esempio n. 5
0
    public bool Execute()
    {
        BuildEngine.LogMessageEvent(new BuildMessageEventArgs(string.Format("Fody (version {0}) Executing", GetType().Assembly.GetName().Version), "", "Fody", Microsoft.Build.Framework.MessageImportance.High));

        var stopwatch = Stopwatch.StartNew();

        Logger = new BuildLogger(MessageImportance)
                     {
                         BuildEngine = BuildEngine,
                     };

        try
        {
            Inner();
            return !Logger.ErrorOccurred;
        }
        catch (Exception exception)
        {
            Logger.LogError(exception.ToFriendlyString());
            return false;
        }
        finally
        {
            stopwatch.Stop();
            Logger.Flush();
            BuildEngine.LogMessageEvent(new BuildMessageEventArgs(string.Format("\tFinished Fody {0}ms.", stopwatch.ElapsedMilliseconds), "", "Fody", Microsoft.Build.Framework.MessageImportance.High));
        }
    }
Esempio n. 6
0
    public bool Execute()
    {
        BuildEngine.LogMessageEvent(new BuildMessageEventArgs(string.Format("Fody (version {0}) Executing", GetType().Assembly.GetName().Version), "", "Fody", Microsoft.Build.Framework.MessageImportance.High));

        var stopwatch = Stopwatch.StartNew();

        Logger = new BuildLogger(MessageImportance)
        {
            BuildEngine = BuildEngine,
        };

        try
        {
            Inner();
            return(!Logger.ErrorOccurred);
        }
        catch (Exception exception)
        {
            Logger.LogError(exception.ToFriendlyString());
            return(false);
        }
        finally
        {
            stopwatch.Stop();
            Logger.Flush();
            BuildEngine.LogMessageEvent(new BuildMessageEventArgs(string.Format("\tFinished Fody {0}ms.", stopwatch.ElapsedMilliseconds), "", "Fody", Microsoft.Build.Framework.MessageImportance.High));
        }
    }
Esempio n. 7
0
    public bool Execute()
    {
        var executingMessage = string.Format("Fody (version {0}) Executing", typeof(Processor).Assembly.GetName().Version);

        BuildEngine.LogMessageEvent(new BuildMessageEventArgs(executingMessage, "", "Fody", MSMessageEnum.High));

        var stopwatch = Stopwatch.StartNew();

        Logger = new BuildLogger
        {
            BuildEngine = BuildEngine,
        };

        try
        {
            Inner();
            return(!Logger.ErrorOccurred);
        }
        catch (Exception exception)
        {
            Logger.LogError(exception.ToFriendlyString());
            return(false);
        }
        finally
        {
            var finishedMessage = string.Format("\tFinished Fody {0}ms.", stopwatch.ElapsedMilliseconds);
            BuildEngine.LogMessageEvent(new BuildMessageEventArgs(finishedMessage, "", "Fody", MSMessageEnum.High));
        }
    }
        public override BuildPipelineCodes Convert(AssetBundleBuild[] input, out BuildInput output)
        {
            StartProgressBar(input);

            // If enabled, try loading from cache
            var hash = CalculateInputHash(input);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out output))
            {
                EndProgressBar();
                return(BuildPipelineCodes.SuccessCached);
            }

            // Convert inputs
            output = new BuildInput();

            if (input.IsNullOrEmpty())
            {
                BuildLogger.LogError("Unable to continue packing. Input is null or empty!");
                EndProgressBar();
                return(BuildPipelineCodes.Error);
            }

            output.definitions = new BuildInput.Definition[input.Length];
            for (var i = 0; i < input.Length; i++)
            {
                output.definitions[i].assetBundleName = input[i].assetBundleName;
                output.definitions[i].explicitAssets  = new AssetIdentifier[input[i].assetNames.Length];
                for (var j = 0; j < input.Length; j++)
                {
                    UpdateProgressBar(input[i].assetNames[j]);
                    var guid = AssetDatabase.AssetPathToGUID(input[i].assetNames[j]);
                    output.definitions[i].explicitAssets[j].asset = new GUID(guid);
                    if (input[i].addressableNames.IsNullOrEmpty() || input[i].addressableNames.Length <= j || string.IsNullOrEmpty(input[i].addressableNames[j]))
                    {
                        output.definitions[i].explicitAssets[j].address = input[i].assetNames[j];
                    }
                    else
                    {
                        output.definitions[i].explicitAssets[j].address = input[i].addressableNames[j];
                    }
                }
            }

            // Cache results
            if (UseCache && !BuildCache.SaveCachedResults(hash, output))
            {
                BuildLogger.LogWarning("Unable to cache AssetBundleBuildConverter results.");
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
Esempio n. 9
0
        /// <summary>
        /// Basic run implementation that takes a set of tasks, a context, and runs returning the build results.
        /// <seealso cref="IBuildTask"/>, <seealso cref="IBuildContext"/>, and <seealso cref="ReturnCode"/>
        /// </summary>
        /// <param name="pipeline">The set of build tasks to run.</param>
        /// <param name="context">The build context to use for this run.</param>
        /// <returns>Return code with status information about success or failure causes.</returns>
        public static ReturnCode Run(IList <IBuildTask> pipeline, IBuildContext context)
        {
            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (pipeline == null)
            {
                BuildLogger.LogException(new ArgumentNullException("pipeline"));
                return(ReturnCode.Exception);
            }

            // Avoid throwing exceptions in here as we don't want them bubbling up to calling user code
            if (context == null)
            {
                BuildLogger.LogException(new ArgumentNullException("context"));
                return(ReturnCode.Exception);
            }

            IProgressTracker tracker;

            if (context.TryGetContextObject(out tracker))
            {
                tracker.TaskCount = pipeline.Count;
            }

            context.TryGetContextObject(out IBuildLogger logger);

            foreach (IBuildTask task in pipeline)
            {
                {
                    try
                    {
                        if (!tracker.UpdateTaskUnchecked(task.GetType().Name.HumanReadable()))
                        {
                            return(ReturnCode.Canceled);
                        }

                        ContextInjector.Inject(context, task);
                        ReturnCode result;
                        using (logger.ScopedStep(LogLevel.Info, task.GetType().Name))
                            result = task.Run();
                        if (result < ReturnCode.Success)
                        {
                            return(result);
                        }
                        ContextInjector.Extract(context, task);
                    }
                    catch (Exception e)
                    {
                        BuildLogger.LogError("Build Task {0} failed with exception:\n{1}\n{2}", task.GetType().Name, e.Message, e.StackTrace);
                        return(ReturnCode.Exception);
                    }
                }
            }

            return(ReturnCode.Success);
        }
Esempio n. 10
0
    void Inner()
    {
        ValidateProjectPath();

        ValidateAssemblyPath();

        ConfigFiles = ConfigFileFinder.FindWeaverConfigs(SolutionDirectory, ProjectDirectory, Logger);

        if (!ShouldStartSinceFileChanged())
        {
            if (!CheckForWeaversXmlChanged())
            {
                FindWeavers();

                if (WeaversHistory.HasChanged(Weavers.Select(x => x.AssemblyPath)))
                {
                    Logger.LogError("A re-build is required because a weaver has changed.");
                }
            }
            return;
        }

        ValidateSolutionPath();

        FindWeavers();

        if (Weavers.Count == 0)
        {
            Logger.LogError("No configured weavers. It is possible you have not installed a weaver or have installed a fody weaver nuget into a project type that does not support install.ps1. You may need to add that weaver to FodyWeavers.xml manually. eg. <Weavers><WeaverName/></Weavers>. see https://github.com/Fody/Fody/wiki/SampleUsage");
            return;
        }
        lock (locker)
        {
            ExecuteInOwnAppDomain();
        }

        FlushWeaversXmlHistory();
    }
Esempio n. 11
0
        public override BuildPipelineCodes Convert(BuildDependencyInfo buildInfo, out BuildWriteInfo writeInfo)
        {
            StartProgressBar("Generating Build Commands", buildInfo.bundleToAssets.Count);

            Hash128 hash = CalculateInputHash(buildInfo);

            if (UseCache && BuildCache.TryLoadCachedResults(hash, out writeInfo))
            {
                writeInfo = new BuildWriteInfo();
                EndProgressBar();
                return(BuildPipelineCodes.SuccessCached);
            }

            writeInfo = new BuildWriteInfo();
            foreach (var bundle in buildInfo.bundleToAssets)
            {
                if (!UpdateProgressBar("Generating Build Commands"))
                {
                    return(BuildPipelineCodes.Canceled);
                }

                // TODO: Handle Player Data & Raw write formats
                if (IsAssetBundle(bundle.Value))
                {
                    var op = CreateAssetBundleWriteOperation(bundle.Key, bundle.Value, buildInfo);
                    writeInfo.assetBundles.Add(bundle.Key, op);
                }
                else if (IsSceneBundle(bundle.Value))
                {
                    var ops = CreateSceneBundleWriteOperations(bundle.Key, bundle.Value, buildInfo);
                    writeInfo.sceneBundles.Add(bundle.Key, ops);
                }
                else
                {
                    BuildLogger.LogError("Bundle '{0}' contains mixed assets and scenes.", bundle.Key);
                }
            }

            if (UseCache && !BuildCache.SaveCachedResults(hash, writeInfo))
            {
                BuildLogger.LogWarning("Unable to cache CommandSetProcessor results.");
            }

            if (!EndProgressBar())
            {
                return(BuildPipelineCodes.Canceled);
            }
            return(BuildPipelineCodes.Success);
        }
Esempio n. 12
0
        private bool ValidateCommand(BuildCommandSet.Command bundle)
        {
            if (bundle.explicitAssets.IsNullOrEmpty())
            {
                BuildLogger.LogWarning("Asset bundle '{0}' does not have any explicit assets defined.", bundle.assetBundleName);
            }
            else
            {
                foreach (var asset in bundle.explicitAssets)
                {
                    if (string.IsNullOrEmpty(asset.address))
                    {
                        BuildLogger.LogWarning("Asset bundle '{0}' has an asset '{1}' with an empty addressable name.", bundle.assetBundleName, asset.asset);
                    }

                    if (asset.includedObjects.IsNullOrEmpty() && asset.includedObjects.IsNullOrEmpty())
                    {
                        BuildLogger.LogWarning("Asset bundle '{0}' has an asset '{1}' with no objects to load.", bundle.assetBundleName, asset.asset);
                    }
                }
            }

            if (bundle.assetBundleObjects.IsNullOrEmpty())
            {
                BuildLogger.LogWarning("Asset bundle '{0}' does not have any serialized objects.", bundle.assetBundleName);
            }
            else
            {
                var localIDs = new HashSet <long>();
                foreach (var serializedInfo in bundle.assetBundleObjects)
                {
                    if (serializedInfo.serializationIndex == 1)
                    {
                        BuildLogger.LogError("Unable to continue resource writing. Asset bundle '{0}' has a serialized object with index of '1'. This is a reserved index and can not be used.",
                                             bundle.assetBundleName);
                        return(false);
                    }

                    if (!localIDs.Add(serializedInfo.serializationIndex))
                    {
                        BuildLogger.LogError("Unable to continue resource writing. Asset bundle '{0}' has multiple serialized objects with the same index '{1}'. Each serialized object must have a unique index.",
                                             bundle.assetBundleName, serializedInfo.serializationIndex);
                        return(false);
                    }
                }
            }

            return(true);
        }
Esempio n. 13
0
        /// <summary>
        /// 取得输出目录.
        /// </summary>
        /// <returns>The output dir.</returns>
        /// <param name="iTarget">打包目标类型.</param>
        /// <param name="iOutputDir">输出目录(未指定:默认输出根目录).</param>
        private static string GetOutputDir(BuildTarget iTarget, string iOutputDir = null)
        {
            string outputRootDir = iOutputDir;

            if (string.IsNullOrEmpty(outputRootDir) == true)
            {
                outputRootDir = _defaultOutputRootDir;
            }

            if (Directory.Exists(outputRootDir) == false)
            {
                BuildLogger.LogWarning("The directory is not exist, so to create.(dir:{0})",
                                       outputRootDir);
                Directory.CreateDirectory(outputRootDir);
            }
            if (Directory.Exists(outputRootDir) == false)
            {
                BuildLogger.LogError("[Directory Create Failed] -> Dir:{0}", outputRootDir);
                return(null);
            }
            else
            {
                BuildLogger.LogMessage("[Directory Create Successed] -> Dir:{0}", outputRootDir);
            }
            string outputDir = string.Format("{0}/{1}", outputRootDir, iTarget.ToString());

            if (Directory.Exists(outputDir) == false)
            {
                BuildLogger.LogWarning("The directory is not exist, so to create.(dir:{0})",
                                       outputDir);
                Directory.CreateDirectory(outputDir);
            }
            if (Directory.Exists(outputDir) == false)
            {
                BuildLogger.LogError("[Directory Create Failed] -> Dir:{0}", outputDir);
                return(null);
            }
            else
            {
                BuildLogger.LogMessage("[Directory Create Successed] -> Dir:{0}", outputDir);
            }
            return(outputDir);
        }
Esempio n. 14
0
    void Inner()
    {
        ValidateProjectPath();

        ValidateAssemblyPath();

        ConfigFiles = ConfigFileFinder.FindWeaverConfigs(SolutionDirectory, ProjectDirectory, Logger);

        if (!ShouldStartSinceFileChanged())
        {
            if (!CheckForWeaversXmlChanged())
            {
                FindWeavers();

                if (WeaversHistory.HasChanged(Weavers.Select(x => x.AssemblyPath)))
                {
                    Logger.LogError("A re-build is required because a weaver has changed.");
                }
            }
            return;
        }

        ValidateSolutionPath();

        FindWeavers();

        if (Weavers.Count == 0)
        {
            Logger.LogWarning(@"No configured weavers. It is possible no weavers have been installed or a weaver has been installed into a project type that does not support install.ps1. It may be necessary to manually add that weaver to FodyWeavers.xm;. eg.
<Weavers>
    <WeaverName/>
</Weavers>
see https://github.com/Fody/Fody/wiki/SampleUsage");
            return;
        }
        lock (locker)
        {
            ExecuteInOwnAssemblyLoadContext();
        }

        FlushWeaversXmlHistory();
    }
Esempio n. 15
0
        private void BuildAssetBundles()
        {
            if (!BuildPathValidator.ValidOutputFolder(m_Settings.outputPath, true))
            {
                EditorUtility.DisplayDialog("Invalid Output Folder", string.Format(BuildPathValidator.kPathNotValidError, m_Settings.outputPath), "Ok");
                return;
            }

            if (!EditorSceneManager.SaveCurrentModifiedScenesIfUserWantsTo())
            {
                return;
            }

            if (m_Settings.useExperimentalPipeline)
            {
                ExperimentalBuildPipeline();
                return;
            }

            var buildTimer = new Stopwatch();

            buildTimer.Start();

            var exitCode = LegacyBuildPipeline();

            buildTimer.Stop();
            if (exitCode == BuildPipelineCodes.Success)
            {
                BuildLogger.Log("Build Asset Bundles successful in: {0:c}", buildTimer.Elapsed);
            }
            else if (exitCode == BuildPipelineCodes.Canceled)
            {
                BuildLogger.LogWarning("Build Asset Bundles canceled in: {0:c}", buildTimer.Elapsed);
            }
            else
            {
                BuildLogger.LogError("Build Asset Bundles failed in: {0:c}. Error: {1}.", buildTimer.Elapsed, exitCode);
            }
        }
Esempio n. 16
0
    void Inner()
    {
        ValidateProjectPath();

        ValidateAssemblyPath();

        FindProjectWeavers();

        if (!ShouldStartSinceFileChanged())
        {
            if (!CheckForWeaversXmlChanged())
            {
                FindWeavers();

                if (WeaversHistory.HasChanged(Weavers.Select(x => x.AssemblyPath)))
                {
                    Logger.LogWarning("A re-build is required to because a weaver changed");
                }
            }
            return;
        }

        ValidateSolutionPath();

        FindWeavers();

        if (Weavers.Count == 0)
        {
            Logger.LogError("You don't seem to have configured any weavers. Try adding a Fody nuget package to your project. Have a look here http://nuget.org/packages?q=fody for the list of available packages.");
            return;
        }
        lock (locker)
        {
            ExecuteInOwnAppDomain();
        }

        FlushWeaversXmlHistory();
    }
        public static BuildPipelineCodes BuildPlayerScripts(ScriptCompilationSettings settings, out ScriptCompilationResult result, bool useCache = true)
        {
            var buildTimer = new Stopwatch();

            buildTimer.Start();

            BuildPipelineCodes exitCode;

            using (var progressTracker = new BuildProgressTracker(1))
            {
                using (var buildCleanup = new BuildStateCleanup(false, kTempPlayerBuildPath))
                {
                    var scriptDependency = new ScriptDependency(useCache, progressTracker);
                    exitCode = scriptDependency.Convert(settings, kTempPlayerBuildPath, out result);
                    if (exitCode < BuildPipelineCodes.Success)
                    {
                        return(exitCode);
                    }
                }
            }

            buildTimer.Stop();
            if (exitCode >= BuildPipelineCodes.Success)
            {
                BuildLogger.Log("Build Player Scripts successful in: {0:c}", buildTimer.Elapsed);
            }
            else if (exitCode == BuildPipelineCodes.Canceled)
            {
                BuildLogger.LogWarning("Build Player Scripts canceled in: {0:c}", buildTimer.Elapsed);
            }
            else
            {
                BuildLogger.LogError("Build Player Scripts failed in: {0:c}", buildTimer.Elapsed);
            }

            return(exitCode);
        }
        public static BuildPipelineCodes BuildAssetBundles(BuildInput input, BuildSettings settings, BuildCompression compression, string outputFolder, out BuildResultInfo result, object callbackUserData = null, bool useCache = true)
        {
            var buildTimer = new Stopwatch();

            buildTimer.Start();

            if (ProjectValidator.HasDirtyScenes())
            {
                result = new BuildResultInfo();
                buildTimer.Stop();
                BuildLogger.LogError("Build Asset Bundles failed in: {0:c}. Error: {1}.", buildTimer.Elapsed, BuildPipelineCodes.UnsavedChanges);
                return(BuildPipelineCodes.UnsavedChanges);
            }

            var exitCode = BuildPipelineCodes.Success;

            result = new BuildResultInfo();

            AssetDatabase.SaveAssets();

            // TODO: Until new AssetDatabaseV2 is online, we need to switch platforms
            EditorUserBuildSettings.SwitchActiveBuildTarget(settings.group, settings.target);

            var stepCount = BundleDependencyStep.StepCount + BundlePackingStep.StepCount + BundleWritingStep.StepCount;

            using (var progressTracker = new BuildProgressTracker(stepCount))
            {
                using (var buildCleanup = new BuildStateCleanup(true, kTempBundleBuildPath))
                {
                    BuildDependencyInfo buildInfo;
                    exitCode = BundleDependencyStep.Build(input, settings, out buildInfo, useCache, progressTracker);
                    if (exitCode < BuildPipelineCodes.Success)
                    {
                        return(exitCode);
                    }

                    if (PostBuildDependency != null)
                    {
                        exitCode = PostBuildDependency.Invoke(buildInfo, callbackUserData);
                        if (exitCode < BuildPipelineCodes.Success)
                        {
                            return(exitCode);
                        }
                    }

                    BuildWriteInfo writeInfo;
                    exitCode = BundlePackingStep.Build(buildInfo, out writeInfo, useCache, progressTracker);
                    if (exitCode < BuildPipelineCodes.Success)
                    {
                        return(exitCode);
                    }

                    if (PostBuildPacking != null)
                    {
                        exitCode = PostBuildPacking.Invoke(buildInfo, writeInfo, callbackUserData);
                        if (exitCode < BuildPipelineCodes.Success)
                        {
                            return(exitCode);
                        }
                    }

                    exitCode = BundleWritingStep.Build(settings, compression, outputFolder, buildInfo, writeInfo, out result, useCache, progressTracker);
                    if (exitCode < BuildPipelineCodes.Success)
                    {
                        return(exitCode);
                    }

                    if (PostBuildWriting != null)
                    {
                        exitCode = PostBuildWriting.Invoke(buildInfo, writeInfo, result, callbackUserData);
                        if (exitCode < BuildPipelineCodes.Success)
                        {
                            return(exitCode);
                        }
                    }
                }
            }

            buildTimer.Stop();
            if (exitCode >= BuildPipelineCodes.Success)
            {
                BuildLogger.Log("Build Asset Bundles successful in: {0:c}", buildTimer.Elapsed);
            }
            else if (exitCode == BuildPipelineCodes.Canceled)
            {
                BuildLogger.LogWarning("Build Asset Bundles canceled in: {0:c}", buildTimer.Elapsed);
            }
            else
            {
                BuildLogger.LogError("Build Asset Bundles failed in: {0:c}. Error: {1}.", buildTimer.Elapsed, exitCode);
            }

            return(exitCode);
        }
Esempio n. 19
0
    void Inner()
    {
        ValidateSolutionPath();
        ValidateProjectPath();
        ValidateAssemblyPath();

        ConfigFiles = ConfigFileFinder.FindWeaverConfigFiles(SolutionDirectory, ProjectDirectory, Logger).ToList();

        if (!ConfigFiles.Any())
        {
            ConfigFiles = new List <WeaverConfigFile>
            {
                ConfigFileFinder.GenerateDefault(ProjectDirectory, Weavers, GenerateXsd)
            };
            Logger.LogWarning($"Could not find a FodyWeavers.xml file at the project level ({ProjectDirectory}). A default file has been created. Please review the file and add it to your project.");
        }

        ConfigEntries = ConfigFileFinder.ParseWeaverConfigEntries(ConfigFiles);

        var extraEntries = ConfigEntries.Values
                           .Where(entry => !entry.ConfigFile.IsGlobal && !Weavers.Any(weaver => string.Equals(weaver.ElementName, entry.ElementName)))
                           .ToArray();

        const string missingWeaversHelp = "Add the desired weavers via their nuget package; see https://github.com/Fody/Fody/wiki on how to migrate InSolution, custom or legacy weavers.";

        if (extraEntries.Any())
        {
            throw new WeavingException($"No weavers found for the configuration entries {string.Join(", ", extraEntries.Select(e => e.ElementName))}. " + missingWeaversHelp);
        }

        if (Weavers.Count == 0)
        {
            throw new WeavingException("No weavers found. " + missingWeaversHelp);
        }

        foreach (var weaver in Weavers)
        {
            if (ConfigEntries.TryGetValue(weaver.ElementName, out var config))
            {
                weaver.Element        = config.Content;
                weaver.ExecutionOrder = config.ExecutionOrder;
            }
            else
            {
                Logger.LogWarning($"No configuration entry found for the installed weaver {weaver.ElementName}. This weaver will be skipped. You may want to add this weaver to your FodyWeavers.xml");
            }
        }

        ConfigFileFinder.EnsureSchemaIsUpToDate(ProjectDirectory, Weavers, GenerateXsd);

        Weavers = Weavers
                  .Where(weaver => weaver.Element != null)
                  .OrderBy(weaver => weaver.ExecutionOrder)
                  .ToList();

        if (TargetAssemblyHasAlreadyBeenProcessed())
        {
            if (WeaversConfigHistory.HasChanged(ConfigFiles) || WeaversHistory.HasChanged(Weavers.Select(x => x.AssemblyPath)))
            {
                Logger.LogError("A re-build is required because a weaver has changed.");

                return;
            }
        }

        lock (mutex)
        {
            ExecuteInOwnAssemblyLoadContext();
        }

        WeaversConfigHistory.RegisterSnapshot(ConfigFiles);
    }
Esempio n. 20
0
        public override bool Execute()
        {
            var referenceCopyLocalPaths = ReferenceCopyLocalFiles.Select(x => x.ItemSpec).ToList();

            var defineConstants = DefineConstants.GetConstants();
            var buildLogger     = new BuildLogger
            {
                BuildEngine = BuildEngine,
            };

            processor = new Processor
            {
                Logger                  = buildLogger,
                AssemblyFilePath        = AssemblyFile,
                IntermediateDirectory   = IntermediateDirectory,
                KeyFilePath             = KeyOriginatorFile ?? AssemblyOriginatorKeyFile,
                SignAssembly            = SignAssembly,
                ProjectDirectory        = ProjectDirectory,
                DocumentationFilePath   = DocumentationFile,
                References              = References,
                SolutionDirectory       = SolutionDirectoryFinder.Find(SolutionDirectory, NCrunchOriginalSolutionDirectory, ProjectDirectory),
                ReferenceCopyLocalPaths = referenceCopyLocalPaths,
                DefineConstants         = defineConstants,
                NuGetPackageRoot        = NuGetPackageRoot,
                MSBuildDirectory        = MSBuildThisFileDirectory,
                WeaverFilesFromProps    = GetWeaverFilesFromProps(),
                DebugSymbols            = GetDebugSymbolsType(),
                GenerateXsd             = GenerateXsd
            };
            var success = processor.Execute();

            if (success)
            {
                var weavers = processor.Weavers.Select(x => x.AssemblyName);
                ExecutedWeavers = string.Join(";", weavers) + ";";

                try
                {
                    File.WriteAllLines(IntermediateCopyLocalFilesCache, processor.ReferenceCopyLocalPaths);
                }
                catch (Exception ex)
                {
                    buildLogger.LogInfo("ProjectDirectory: " + ProjectDirectory);
                    buildLogger.LogInfo("IntermediateDirectory: " + IntermediateDirectory);
                    buildLogger.LogInfo("CurrentDirectory: " + Directory.GetCurrentDirectory());
                    buildLogger.LogInfo("AssemblyFile: " + AssemblyFile);
                    buildLogger.LogInfo("IntermediateCopyLocalFilesCache: " + IntermediateCopyLocalFilesCache);
                    buildLogger.LogError("Error writing IntermediateCopyLocalFilesCache: " + ex.Message);
                    return(false);
                }
            }
            else
            {
                if (File.Exists(IntermediateCopyLocalFilesCache))
                {
                    File.Delete(IntermediateCopyLocalFilesCache);
                }
            }

            return(success);
        }
Esempio n. 21
0
        /// <summary>
        /// 打包资源文件
        /// </summary>
        /// <param name="buildTarget">Build target.</param>
        /// <param name="needCompress">If set to <c>true</c> need compress.</param>
        private static void BuildAssetBundle(BuildTarget buildTarget, bool needCompress = false)
        {
            const string funcBlock = "AssetBundlesBuild.BuildAssetBundle()";

            BuildLogger.OpenBlock(funcBlock);

            // 设置上传的打包类型
            UploadList.GetInstance().BuildTarget = buildTarget.ToString();

            BundlesConfig bcConfig = BundlesConfig.GetInstance();

            if ((null == bcConfig) || (0 >= bcConfig.Resources.Count))
            {
                BuildLogger.LogError("BuildAssetBundle::BundlesConfig is invalid!!!");
                return;
            }

            // 清空依赖关系列表
            BundlesMap bundlesMap = BundlesMap.GetInstance();

            if (null == bundlesMap)
            {
                BuildLogger.LogError("BuildAssetBundle::bundlesMap is invalid!!!");
                return;
            }
            bundlesMap.Clear();

            List <BundleResource> allConfig = bcConfig.Resources;

            // make bundle config
            foreach (BundleResource bc in allConfig)
            {
                // filter file
                if (bc.Mode == BundleMode.OneDir)
                {
                    string    bundleId = BundlesMap.GetBundleID(bc.Path);
                    BundleMap bm       = bundlesMap.GetOrCreateBundlesMap(bundleId);

                    bm.ID   = bundleId;
                    bm.Path = bc.Path;

                    // 取得当前目录的文件列表
                    List <string> files = GetAllFiles(bc.Path);

                    // 遍历文件列表
                    foreach (string file in files)
                    {
                        // .DS_Store文件
                        if (file.EndsWith(".DS_Store") == true)
                        {
                            continue;
                        }
                        // *.meta文件
                        if (file.EndsWith(".meta") == true)
                        {
                            continue;
                        }

                        // 若为忽略文件,则跳过
                        if (bcConfig.isIgnoreFile(bc, file) == true)
                        {
                            bm.RemoveIgnorFile(file);
                            continue;
                        }
                        bm.AddFile(file);
                    }

                    bundlesMap.Maps.Add(bm);
                }
                else if (bc.Mode == BundleMode.SceneOneToOne)
                {
                    // 取得当前目录的文件列表
                    List <string> files = GetAllFiles(bc.Path);

                    foreach (string file in files)
                    {
                        // .DS_Store文件
                        if (file.EndsWith(".DS_Store") == true)
                        {
                            continue;
                        }
                        // *.meta文件
                        if (file.EndsWith(".meta") == true)
                        {
                            continue;
                        }
                        // 若非场景文件,则跳过
                        if (file.EndsWith(".unity") == false)
                        {
                            continue;
                        }

                        // 若为忽略文件,则跳过
                        string    bundleId = BundlesMap.GetBundleID(file);
                        BundleMap bm       = bundlesMap.GetOrCreateBundlesMap(bundleId);
                        if (bcConfig.isIgnoreFile(bc, file) == true)
                        {
                            bm.RemoveIgnorFile(file);
                            continue;
                        }

                        bm.ID   = bundleId;
                        bm.Path = bc.Path;
                        bm.Type = TBundleType.Scene;
                        bm.AddFile(file);

                        bundlesMap.Maps.Add(bm);
                    }
                }
                else if (bc.Mode == BundleMode.FileOneToOne)
                {
                    // 取得当前目录的文件列表
                    List <string> files = GetAllFiles(bc.Path);

                    foreach (string file in files)
                    {
                        // .DS_Store文件
                        if (file.EndsWith(".DS_Store") == true)
                        {
                            continue;
                        }
                        // *.meta文件
                        if (file.EndsWith(".meta") == true)
                        {
                            continue;
                        }

                        // 若为忽略文件,则跳过
                        string    bundleId = BundlesMap.GetBundleID(file);
                        BundleMap bm       = bundlesMap.GetOrCreateBundlesMap(bundleId);
                        if (bcConfig.isIgnoreFile(bc, file) == true)
                        {
                            bm.RemoveIgnorFile(file);
                            continue;
                        }

                        bm.ID   = bundleId;
                        bm.Path = bc.Path;
                        bm.AddFile(file);

                        bundlesMap.Maps.Add(bm);
                    }
                }
                else if (bc.Mode == BundleMode.TopDirOneToOne)
                {
                    // 取得目录列表
                    string[] directories = Directory.GetDirectories(bc.Path);
                    if ((directories == null) || (directories.Length <= 0))
                    {
                        BuildLogger.LogWarning("The no subfolder in this path!!!(dir:{0})",
                                               bc.Path);
                        continue;
                    }

                    foreach (string dir in directories)
                    {
                        // 取得当前目录的文件列表
                        List <string> files = GetAllFiles(dir);

                        string bundleId = BundlesMap.GetBundleID(dir);
                        bundleId = BundlesMap.GetBundleID(dir);
                        if (string.IsNullOrEmpty(bundleId) == true)
                        {
                            continue;
                        }
                        BundleMap bm = bundlesMap.GetOrCreateBundlesMap(bundleId);
                        bm.ID   = bundleId;
                        bm.Path = bc.Path;

                        foreach (string file in files)
                        {
                            // .DS_Store文件
                            if (file.EndsWith(".DS_Store") == true)
                            {
                                continue;
                            }
                            // *.meta文件
                            if (file.EndsWith(".meta") == true)
                            {
                                continue;
                            }

                            // 若为忽略文件,则跳过
                            if (bcConfig.isIgnoreFile(bc, file) == true)
                            {
                                bm.RemoveIgnorFile(file);
                                continue;
                            }

                            bm.AddFile(file);
                        }

                        bundlesMap.Maps.Add(bm);
                    }
                }
            }

            // 目录检测
            string checkDir = UploadList.GetInstance().BundlesOutputDir;

            if (Directory.Exists(checkDir) == false)
            {
                Directory.CreateDirectory(checkDir);
            }
            checkDir = UploadList.GetInstance().BundlesOutputDirOfNormal;
            if (Directory.Exists(checkDir) == false)
            {
                Directory.CreateDirectory(checkDir);
            }
            checkDir = UploadList.GetInstance().BundlesOutputDirOfScene;
            if (Directory.Exists(checkDir) == false)
            {
                Directory.CreateDirectory(checkDir);
            }

            bool successed             = false;
            AssetBundleManifest result = null;

            string[]           allAssets = null;
            AssetBundleBuild[] targets   = null;

            // 一般Bundles
            try {
                targets = bundlesMap.GetAllNormalBundleTargets();
                BuildAssetBundleOptions options = BuildAssetBundleOptions.UncompressedAssetBundle;
                result = BuildPipeline.BuildAssetBundles(
                    UploadList.GetInstance().BundlesOutputDirOfNormal,
                    targets,
                    options,
                    buildTarget);
                BuildLogger.LogMessage(" -> BuildPipeline.BuildAssetBundles");
                if (result != null)
                {
                    allAssets = result.GetAllAssetBundles();
                    if ((allAssets != null) && (targets.Length == allAssets.Length))
                    {
                        successed = true;
                    }
                }
            } catch (Exception exp) {
                BuildLogger.LogException("BuildAssetBundles Detail : {0}", exp.Message);
                successed = false;
            }

            // 更新导出标志位
            if (successed == true)
            {
                BuildLogger.LogMessage(" -> BundlesConfig.UpdateBundleStateWhenCompleted");

                Dictionary <string, string> hashCodes = new Dictionary <string, string>();
                foreach (string asset in allAssets)
                {
                    Hash128 hashCode = result.GetAssetBundleHash(asset);
                    if (string.IsNullOrEmpty(hashCode.ToString()) == true)
                    {
                        continue;
                    }
                    string fileSuffix = UploadList.GetInstance().FileSuffix;
                    string key        = asset;
                    if (string.IsNullOrEmpty(fileSuffix) == false)
                    {
                        fileSuffix = fileSuffix.ToLower();
                        fileSuffix = string.Format(".{0}", fileSuffix);
                        key        = key.Replace(fileSuffix, "");
                    }
                    hashCodes[key] = hashCode.ToString();
                }
                // 初始化检测信息(Hash Code)
                bundlesMap.UpdateUploadList(TBundleType.Normal, hashCodes);
                BuildLogger.LogMessage(" -> BundlesMap.UpdateUploadList Normal");
            }

            // Scene Bundles
            List <SceneBundleInfo> targetScenes = bundlesMap.GetAllSceneBundleTargets();

            if ((targetScenes != null) && (targetScenes.Count > 0))
            {
                foreach (SceneBundleInfo scene in targetScenes)
                {
                    if ((scene == null) ||
                        (scene.GetAllTargets() == null) ||
                        (scene.GetAllTargets().Length <= 0))
                    {
                        continue;
                    }
                    try {
                        BuildOptions options = BuildOptions.BuildAdditionalStreamedScenes;
                        if (TBuildMode.Debug == BuildInfo.GetInstance().BuildMode)
                        {
                            options |= BuildOptions.Development;
                        }
                        string sceneState = BuildPipeline.BuildPlayer(
                            scene.GetAllTargets(),
                            UploadList.GetLocalSceneBundleFilePath(scene.BundleId),
                            buildTarget,
                            options);
                        BuildLogger.LogMessage(" -> BuildPipeline.BuildStreamedSceneAssetBundle(State:{0})", sceneState);
                    } catch (Exception exp) {
                        BuildLogger.LogException("BuildStreamedSceneAssetBundle Detail:{0}", exp.Message);
                        successed = false;
                    }
                }
            }

            // 更新导出标志位
            if (successed == true)
            {
                BuildLogger.LogMessage(" -> BundlesConfig.UpdateBundleStateWhenCompleted");

                // 初始化检测信息(Hash Code)
                bundlesMap.UpdateUploadList(TBundleType.Scene);
                BuildLogger.LogMessage(" -> BundlesMap.UpdateUploadList Scene");
            }

            BuildInfo.GetInstance().ExportToJsonFile();
            BuildLogger.LogMessage(" -> BuildInfo.ExportToJsonFile");

            BuildLogger.CloseBlock();
        }
        public bool Convert(BuildCommandSet input, out BuildCommandSet output, bool useCache = true)
        {
            // If enabled, try loading from cache
            var hash = CalculateInputHash(input);

            if (useCache && LoadFromCache(hash, out output))
            {
                return(true);
            }

            // Convert inputs
            output = input;

            if (input.commands.IsNullOrEmpty())
            {
                return(false);
            }

            // Generate asset lookup
            var assetToBundle   = new Dictionary <GUID, string>();
            var spriteSourceRef = new Dictionary <ObjectIdentifier, AtlasRef>();

            for (var i = 0; i < output.commands.Length; i++)
            {
                if (string.IsNullOrEmpty(output.commands[i].assetBundleName))
                {
                    BuildLogger.LogError("Unable to continue dependency calcualtion. Asset bundle name is null or empty!");
                    return(false);
                }

                if (output.commands[i].explicitAssets.IsNullOrEmpty())
                {
                    BuildLogger.LogError("Asset bundle '{0}' does not have any explicit assets defined.", output.commands[i].assetBundleName);
                    continue;
                }

                for (var j = 0; j < output.commands[i].explicitAssets.Length; j++)
                {
                    string bundleName;
                    if (assetToBundle.TryGetValue(output.commands[i].explicitAssets[j].asset, out bundleName))
                    {
                        if (bundleName == output.commands[i].assetBundleName)
                        {
                            continue;
                        }
                        BuildLogger.LogError("Unable to continue dependency calcualtion. Asset '{0}' added to multiple bundles: '{1}', ,'{2}'!",
                                             output.commands[i].explicitAssets[j].asset, bundleName, output.commands[i].assetBundleName);
                        return(false);
                    }
                    assetToBundle.Add(output.commands[i].explicitAssets[j].asset, output.commands[i].assetBundleName);

                    if (IsAssetSprite(ref output.commands[i].explicitAssets[j]))
                    {
                        spriteSourceRef[output.commands[i].explicitAssets[j].includedObjects[0]] = new AtlasRef(i, j);
                    }
                }
            }

            var dependencies = new HashSet <string>();

            for (var i = 0; i < output.commands.Length; i++)
            {
                if (output.commands[i].assetBundleObjects.IsNullOrEmpty())
                {
                    BuildLogger.LogWarning("Asset bundle '{0}' does not have any serialized objects.", output.commands[i].assetBundleName);
                    continue;
                }

                var j   = 0;
                var end = output.commands[i].assetBundleObjects.Length;
                while (j < end)
                {
                    if (output.commands[i].assetBundleObjects[j].serializationObject.filePath == kUnityDefaultResourcePath)
                    {
                        output.commands[i].assetBundleObjects.Swap(j, --end);
                        continue;
                    }

                    AtlasRef refCount;
                    if (spriteSourceRef.TryGetValue(output.commands[i].assetBundleObjects[j].serializationObject, out refCount) && refCount.bundle != i)
                    {
                        refCount.count++;
                        spriteSourceRef[output.commands[i].assetBundleObjects[j].serializationObject] = refCount;
                    }

                    string dependency;
                    if (!assetToBundle.TryGetValue(output.commands[i].assetBundleObjects[j].serializationObject.guid, out dependency))
                    {
                        j++;
                        continue;
                    }

                    if (dependency == output.commands[i].assetBundleName)
                    {
                        j++;
                        continue;
                    }

                    dependencies.Add(dependency);
                    output.commands[i].assetBundleObjects.Swap(j, --end);
                }
                Array.Resize(ref output.commands[i].assetBundleObjects, end);
                // Sorting is unneccessary - just makes it more human readable
                Array.Sort(output.commands[i].assetBundleObjects, kSerializationInfoComparer);
                output.commands[i].assetBundleDependencies = dependencies.OrderBy(s => s).ToArray();
                dependencies.Clear();
            }

            // Remove source textures if no references
            foreach (var refCount in spriteSourceRef)
            {
                if (refCount.Value.count != 0)
                {
                    continue;
                }

                int i   = refCount.Value.bundle;
                int j   = refCount.Value.asset;
                int end = output.commands[i].explicitAssets[j].includedObjects.Length;
                output.commands[i].explicitAssets[j].includedObjects.Swap(0, end - 1);
                Array.Resize(ref output.commands[i].explicitAssets[j].includedObjects, end - 1);
                Array.Sort(output.commands[i].explicitAssets[j].includedObjects, kObjectIdentifierComparer);

                end = output.commands[refCount.Value.bundle].assetBundleObjects.Length;
                for (j = 0; j < end; j++)
                {
                    if (output.commands[i].assetBundleObjects[j].serializationObject != refCount.Key)
                    {
                        continue;
                    }

                    output.commands[i].assetBundleObjects.Swap(j, --end);
                }
                Array.Resize(ref output.commands[i].assetBundleObjects, end);
                Array.Sort(output.commands[i].assetBundleObjects, kSerializationInfoComparer);
            }

            // Cache results
            if (useCache)
            {
                SaveToCache(hash, output);
            }
            return(true);
        }
        public bool Convert(BuildInput input, BuildTarget target, out BuildCommandSet output, bool useCache = true)
        {
            // If enabled, try loading from cache
            var hash = CalculateInputHash(input, target);

            if (useCache && LoadFromCache(hash, out output))
            {
                return(true);
            }

            // Convert inputs
            output = new BuildCommandSet();

            if (input.definitions.IsNullOrEmpty())
            {
                return(false);
            }

            var o = -1;

            output.commands = new BuildCommandSet.Command[input.definitions.Length];
            for (var i = 0; i < input.definitions.Length; i++)
            {
                // If this definition has no assets, it's empty and we don't want to write anything out
                if (input.definitions[i].explicitAssets.IsNullOrEmpty())
                {
                    BuildLogger.LogError("Asset bundle '{0}' does not have any explicit assets defined.", input.definitions[i].assetBundleName);
                    continue;
                }
                o++;

                var allObjectIDs = new HashSet <ObjectIdentifier>();
                output.commands[o].assetBundleName = input.definitions[i].assetBundleName;
                output.commands[o].explicitAssets  = new BuildCommandSet.AssetLoadInfo[input.definitions[i].explicitAssets.Length];
                for (var j = 0; j < input.definitions[i].explicitAssets.Length; j++)
                {
                    output.commands[o].explicitAssets[j].asset   = input.definitions[i].explicitAssets[j].asset;
                    output.commands[o].explicitAssets[j].address = string.IsNullOrEmpty(input.definitions[i].explicitAssets[j].address) ?
                                                                   AssetDatabase.GUIDToAssetPath(input.definitions[i].explicitAssets[j].asset.ToString()) : input.definitions[i].explicitAssets[j].address;
                    output.commands[o].explicitAssets[j].includedObjects   = BuildInterface.GetPlayerObjectIdentifiersInAsset(input.definitions[i].explicitAssets[j].asset, target);
                    output.commands[o].explicitAssets[j].referencedObjects = BuildInterface.GetPlayerDependenciesForObjects(output.commands[i].explicitAssets[j].includedObjects, target);

                    allObjectIDs.UnionWith(output.commands[i].explicitAssets[j].includedObjects);
                    allObjectIDs.UnionWith(output.commands[i].explicitAssets[j].referencedObjects);
                }

                var k = 0;
                output.commands[o].assetBundleObjects = new BuildCommandSet.SerializationInfo[allObjectIDs.Count];
                foreach (var objectID in allObjectIDs)
                {
                    output.commands[o].assetBundleObjects[k].serializationObject = objectID;
                    output.commands[o].assetBundleObjects[k].serializationIndex  = CalculateSerializationIndexFromObjectIdentifier(objectID);
                    k++;
                }
                // Sorting is unneccessary - just makes it more human readable
                Array.Sort(output.commands[o].assetBundleObjects, kCompareer);
            }
            Array.Resize(ref output.commands, o + 1);

            // Cache results
            if (useCache)
            {
                SaveToCache(hash, output);
            }
            return(true);
        }
        public bool Convert(BuildCommandSet commands, BuildOutput output, uint[] crcs, string outputFolder, out string[] manifestFiles, bool useCache = true)
        {
            // If enabled, try loading from cache
            var hash = CalculateInputHash(commands, output, crcs, outputFolder);

            if (useCache && LoadFromCache(hash, outputFolder, out manifestFiles))
            {
                return(true);
            }

            // Convert inputs
            var manifests = new List <string>();

            if (output.results.IsNullOrEmpty())
            {
                manifestFiles = manifests.ToArray();
                BuildLogger.LogError("Unable to continue writting manifests. No asset bundle results.");
                return(false);
            }

            // TODO: Prepare settings.outputFolder
            Directory.CreateDirectory(outputFolder);

            for (var i = 0; i < output.results.Length; i++)
            {
                var manifestPath = GetManifestFilePath(output.results[i].assetBundleName, outputFolder);
                manifests.Add(string.Format("{0}.manifest", output.results[i].assetBundleName));
                using (var stream = new StreamWriter(manifestPath))
                {
                    // TODO: Implement assetFileHash, typeTreeHash, and includedTypes at LLAPI or HLAPI
                    stream.WriteLine("ManifestFileVersion: 0");
                    stream.WriteLine("CRC: {0}", crcs[i]);
                    stream.WriteLine("Hashes:");
                    stream.WriteLine("  AssetFileHash:");
                    stream.WriteLine("    serializedVersion: 2");
                    stream.WriteLine("    Hash: 1"); // output.assetFileHash
                    stream.WriteLine("  TypeTreeHash:");
                    stream.WriteLine("    serializedVersion: 2");
                    stream.WriteLine("    Hash: 1"); // output.typeTreeHash
                    stream.WriteLine("HashAppended: 0");

                    //if (output.results[i].includedTypes.IsNullOrEmpty())
                    stream.WriteLine("ClassTypes: []");
                    //else
                    //{
                    //    stream.WriteLine("ClassTypes:");
                    //    for (var j = 0; j < output.results[i].includedTypes.Length; j++)
                    //    {
                    //        stream.Write("- Class: {0}", output.results[i].includedTypes.TypeID());
                    //        if (output.results[i].includedTypes.IsScript())
                    //            stream.WriteLine(" Script: {0}", output.results[i].includedTypes.ScriptID());
                    //        else
                    //            stream.WriteLine(" Script: {instanceID: 0}");
                    //    }
                    //}

                    if (commands.commands.IsNullOrEmpty() || commands.commands.Length <= i)
                    {
                        stream.WriteLine("Assets: []");
                        stream.WriteLine("Dependencies: []");
                        continue;
                    }

                    if (!commands.commands[i].explicitAssets.IsNullOrEmpty())
                    {
                        stream.WriteLine("Assets:");
                        for (var j = 0; j < commands.commands[i].explicitAssets.Length; j++)
                        {
                            // TODO: Create GUIDToAssetPath that takes GUID struct
                            stream.WriteLine("- {0}", AssetDatabase.GUIDToAssetPath(commands.commands[i].explicitAssets[j].asset.ToString()));
                        }
                    }
                    else
                    {
                        stream.WriteLine("Assets: []");
                    }

                    if (!commands.commands[i].assetBundleDependencies.IsNullOrEmpty())
                    {
                        stream.WriteLine("Dependencies:");
                        for (var j = 0; j < commands.commands[i].assetBundleDependencies.Length; j++)
                        {
                            stream.WriteLine("- {0}", commands.commands[i].assetBundleDependencies[j]);
                        }
                    }
                    else
                    {
                        stream.WriteLine("Dependencies: []");
                    }
                }
            }

            manifestFiles = manifests.ToArray();

            // Cache results
            if (useCache)
            {
                SaveToCache(hash, outputFolder, manifestFiles);
            }
            return(true);
        }