Exemplo n.º 1
0
        private IEnumerable<string> DeployRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mScriptsPath))
            {
                yield return string.Format("Scripts: {0}", mScriptsPath);

                var sb = new StringBuilder();
                GenerateScript(runContext.Environment, sb, true, mScriptsPath).RunToEnd();

                var script = sb.ToString();
                yield return "Running script...";

                if (!runContext.DryRun)
                {
                    using (var sqlcmdResult = SqlUtils.SqlCmdExec(mDatabaseConnection, script))
                    using (runContext.DepthScope())
                    {
                        foreach (var processOutputLine in sqlcmdResult.GetOutput())
                        {
                            if (processOutputLine.OutputType == ProcessOutputLine.OutputTypeEnum.StandardError)
                                yield return processOutputLine.Line;
                        }

                        if (sqlcmdResult.ExitCode != 0)
                        {
                            runContext.SetError();
                        }
                    }
                }
            }
        }
Exemplo n.º 2
0
        private IEnumerable<string> GenerateScriptsRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mScriptsPath))
            {
                if (!Directory.Exists(runContext.Config.ScriptsPath))
                {
                    yield return string.Format("Creating directory {0}", runContext.Config.ScriptsPath);
                    if (!runContext.DryRun)
                        Directory.CreateDirectory(runContext.Config.ScriptsPath);
                }

                var scriptFile = Path.Combine(runContext.Config.ScriptsPath, mReleaseInfo.Branch.Name + "$" + mReleaseInfo.Name + @".sql");
                yield return string.Format("Generating {0}", scriptFile);

                var sb = new StringBuilder();
                using (runContext.DepthScope())
                {
                    foreach (var log in GenerateScript(runContext.Environment, sb, false, mScriptsPath))
                    {
                        yield return log;
                    }
                }

                if (!runContext.DryRun)
                {
                    File.WriteAllText(scriptFile, sb.ToString());
                }
            }
        }
Exemplo n.º 3
0
        private IEnumerable <string> DeployRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mScriptsPath))
            {
                yield return(string.Format("Scripts: {0}", mScriptsPath));

                var sb = new StringBuilder();
                GenerateScript(runContext.Environment, sb, true, mScriptsPath).RunToEnd();

                var script = sb.ToString();
                yield return("Running script...");

                if (!runContext.DryRun)
                {
                    using (var sqlcmdResult = SqlUtils.SqlCmdExec(mDatabaseConnection, script))
                        using (runContext.DepthScope())
                        {
                            foreach (var processOutputLine in sqlcmdResult.GetOutput())
                            {
                                if (processOutputLine.OutputType == ProcessOutputLine.OutputTypeEnum.StandardError)
                                {
                                    yield return(processOutputLine.Line);
                                }
                            }

                            if (sqlcmdResult.ExitCode != 0)
                            {
                                runContext.SetError();
                            }
                        }
                }
            }
        }
Exemplo n.º 4
0
        private IEnumerable <string> GenerateScriptsRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mScriptsPath))
            {
                if (!Directory.Exists(runContext.Config.ScriptsPath))
                {
                    yield return(string.Format("Creating directory {0}", runContext.Config.ScriptsPath));

                    if (!runContext.DryRun)
                    {
                        Directory.CreateDirectory(runContext.Config.ScriptsPath);
                    }
                }

                var scriptFile = Path.Combine(runContext.Config.ScriptsPath, mReleaseInfo.Branch.Name + "$" + mReleaseInfo.Name + @".sql");
                yield return(string.Format("Generating {0}", scriptFile));

                var sb = new StringBuilder();
                using (runContext.DepthScope())
                {
                    foreach (var log in GenerateScript(runContext.Environment, sb, false, mScriptsPath))
                    {
                        yield return(log);
                    }
                }

                if (!runContext.DryRun)
                {
                    File.WriteAllText(scriptFile, sb.ToString());
                }
            }
        }
Exemplo n.º 5
0
        public IEnumerable<string> Run(string action, ComponentRunContext runContext)
        {
            var pre = GetPreComponent(action, runContext);
            if (pre != null)
            {
                foreach (var log in pre.Run(action, runContext))
                {
                    yield return log;
                }
            }

            using (runContext.DepthScope())
            {
                foreach (var log in GetComponentsToRun(action, runContext).Run(action, runContext))
                {
                    yield return log;
                }
            }

            var post = GetPostComponent(action, runContext);
            if (post != null)
            {
                foreach (var log in post.Run(action, runContext))
                {
                    yield return log;
                }
            }
        }
        public IEnumerable <string> Run(string action, ComponentRunContext runContext)
        {
            var pre = GetPreComponent(action, runContext);

            if (pre != null)
            {
                foreach (var log in pre.Run(action, runContext))
                {
                    yield return(log);
                }
            }

            using (runContext.DepthScope())
            {
                foreach (var log in GetComponentsToRun(action, runContext).Run(action, runContext))
                {
                    yield return(log);
                }
            }

            var post = GetPostComponent(action, runContext);

            if (post != null)
            {
                foreach (var log in post.Run(action, runContext))
                {
                    yield return(log);
                }
            }
        }
Exemplo n.º 7
0
        private IEnumerable <string> MakeReleasePackageRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mScriptsPath))
            {
                var packageDir = runContext.Config.GetPackageDirectory(mReleaseInfo, "Scripts");
                yield return(string.Format("Scripts {0} -> {1}", mScriptsPath, packageDir));

                using (runContext.DepthScope())
                {
                    var synchronizer = new FileSynchronizer(mScriptsPath, packageDir, GetScriptsFilterByEnvironment(runContext.Environment));
                    foreach (var log in synchronizer.Run(action, runContext))
                    {
                        yield return(log);
                    }
                }

                var scriptName = mReleaseInfo.Name + @".sql";
                yield return(string.Format("Generating script {0}", scriptName));

                var sb = new StringBuilder();
                GenerateScript(runContext.Environment, sb, false, packageDir).RunToEnd();

                if (!runContext.DryRun)
                {
                    File.WriteAllText(runContext.Config.GetPackageDirectory(mReleaseInfo.Branch, scriptName), sb.ToString());
                }
            }
        }
Exemplo n.º 8
0
        public IEnumerable<string> Run(string action, ComponentRunContext runContext)
        {
            Func<string, ComponentRunContext, IEnumerable<string>> runner;
            if (mRunners.TryGetValue(action, out runner))
            {
                return runner(action, runContext);
            }

            return Enumerable.Empty<string>();
        }
Exemplo n.º 9
0
        public IEnumerable <string> Run(string action, ComponentRunContext runContext)
        {
            Func <string, ComponentRunContext, IEnumerable <string> > runner;

            if (mRunners.TryGetValue(action, out runner))
            {
                return(runner(action, runContext));
            }

            return(Enumerable.Empty <string>());
        }
        private IEnumerable<string> DeployRun(string action, ComponentRunContext runContext)
        {
            var sb = new StringBuilder();
            var dbName = SqlUtils.ToBracketedIdentifier(mDatabaseInfo.Name);
            var sqlParams = new SqlParamCollection();

            sb.AppendFormat(
                "USE [master]\n" +
                "IF db_id(@dbName) IS NOT NULL\n" +
                "  ALTER DATABASE {0} SET SINGLE_USER WITH ROLLBACK IMMEDIATE\n" +
                "RESTORE DATABASE {0} FROM DISK = @backupFile WITH FILE = 1, NOUNLOAD, STATS = 5",
                dbName);

            sqlParams.Add("@dbName", SqlDbType.NVarChar).Value = mDatabaseInfo.Name;
            sqlParams.Add("@backupFile", SqlDbType.NVarChar).Value = mDatabaseInfo.BackupFilePath;

            if (mDatabaseInfo.Relocate)
            {
                var names = SqlUtils.GetLogicalAndPhysicalNamesFromBackupFile(mDatabaseInfo.Connection, mDatabaseInfo.BackupFilePath);

                var i = 0;
                foreach (var tuple in names)
                {
                    var logical = string.Format("@l{0}", i);
                    var physical = string.Format("@p{0}", i);
                    sb.AppendFormat(",\n  MOVE {0} TO {1}", logical, physical);

                    var destPath = GetRelocation(tuple.Item2);
                    sqlParams.Add(logical, SqlDbType.NVarChar).Value = tuple.Item1;
                    sqlParams.Add(physical, SqlDbType.NVarChar).Value = destPath;

                    ++i;
                }
            }

            sb.AppendFormat(
                "\nALTER DATABASE {0} SET MULTI_USER\n", dbName);

            yield return string.Format("Restoring {0}", mDatabaseInfo.Name);

            if (!runContext.DryRun)
            {
                using (var process = SqlUtils.Exec(mDatabaseInfo.Connection, sb.ToString(), sqlParams))
                {
                    foreach (var processOutputLine in process.GetOutput())
                    {
                        yield return processOutputLine.Line;
                    }
                }
            }

            yield return "Database restore completed.";
        }
Exemplo n.º 11
0
        public static IEnumerable<string> Run(this IEnumerable<IComponent> components, string action, ComponentRunContext runContext)
        {
            foreach (var component in components)
            {
                foreach (var log in component.Run(action, runContext))
                {
                    yield return log;

                    if (runContext.Error)
                        yield break;
                }
            }
        }
Exemplo n.º 12
0
        private IEnumerable <string> DeployRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mReportsPath))
            {
                yield return(string.Format("Reports: {0} -> {1}", mReportsPath, mReleaseInfo.Branch.DeployPath));

                using (runContext.DepthScope())
                {
                    var synchronizer = new FileSynchronizer(mReportsPath, mReleaseInfo.Branch.DeployPath, ReportFileRegex);
                    foreach (var log in synchronizer.Run(action, runContext))
                    {
                        yield return(log);
                    }
                }
            }
        }
Exemplo n.º 13
0
        private IEnumerable<string> DeployRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mTemplatesPath))
            {
                yield return string.Format("Templates {0} -> {1}", mTemplatesPath, mReleaseInfo.Branch.DeployPath);

                using (runContext.DepthScope())
                {
                    var synchronizer = new FileSynchronizer(mTemplatesPath, mReleaseInfo.Branch.DeployPath, TemplateFileRegex);
                    foreach (var log in synchronizer.Run(action, runContext))
                    {
                        yield return log;
                    }
                }
            }
        }
Exemplo n.º 14
0
        protected override IEnumerable<IComponent> GetComponentsToRun(string action, ComponentRunContext runContext)
        {
            var graph = new DependencyGraph<IComponent>();

            var prerequisites = new PrerequisitesComponent(mReleaseInfo);
            var tplComponent = new TemplatesComponent(mReleaseInfo);
            var reportsComponent = new ReportsComponent(mReleaseInfo);
            var scriptsComponent = new ScriptsComponent(mReleaseInfo, mDbConnection);

            graph.AddDependency(prerequisites, tplComponent);
            graph.AddDependency(prerequisites, reportsComponent);
            graph.AddDependency(prerequisites, scriptsComponent);
            graph.AddDependency(tplComponent, scriptsComponent);
            graph.AddDependency(reportsComponent, scriptsComponent);

            return graph.GetPath();
        }
Exemplo n.º 15
0
        private IEnumerable <string> MakeReleasePackageRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mReportsPath))
            {
                var packageDir = runContext.Config.GetPackageDirectory(mReleaseInfo, "Reports+Templates");
                yield return(string.Format("Reports {0} -> {1}", mReportsPath, packageDir));

                using (runContext.DepthScope())
                {
                    var synchronizer = new FileSynchronizer(mReportsPath, packageDir, ReportFileRegex);
                    foreach (var log in synchronizer.Run(action, runContext))
                    {
                        yield return(log);
                    }
                }
            }
        }
Exemplo n.º 16
0
        private IEnumerable<string> MakeReleasePackageRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mTemplatesPath))
            {
                var packageDir = runContext.Config.GetPackageDirectory(mReleaseInfo, "Reports+Templates");
                yield return string.Format("Templates {0} -> {1}", mTemplatesPath, packageDir);

                using (runContext.DepthScope())
                {
                    var synchronizer = new FileSynchronizer(mTemplatesPath, packageDir, TemplateFileRegex);
                    foreach (var log in synchronizer.Run(action, runContext))
                    {
                        yield return log;
                    }
                }
            }
        }
Exemplo n.º 17
0
            private IEnumerable<string> MakeReleasePackageRun(string action, ComponentRunContext runContext)
            {
                var packageDirectory = runContext.Config.GetPackageDirectory(mReleaseInfo);
                if (Directory.Exists(packageDirectory))
                {
                    yield return string.Format("Erasing contents of directory {0}", packageDirectory);
                    if (!runContext.DryRun)
                        FileUtils.DeleteDirectory(packageDirectory);
                }

                if (!Directory.Exists(packageDirectory))
                {
                    yield return string.Format("Creating directory {0}", packageDirectory);
                    if (!runContext.DryRun)
                        Directory.CreateDirectory(packageDirectory);
                }
            }
        public IEnumerable <string> Run(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mSourcePath))
            {
                if (!Directory.Exists(mDestinationPath))
                {
                    yield return(string.Format("Creating {0}", mDestinationPath));

                    if (!runContext.DryRun)
                    {
                        Directory.CreateDirectory(mDestinationPath);
                    }
                }

                foreach (var f in FileUtils.EnumerateFiles2(mSourcePath, mFilter))
                {
                    var fileName = f.FileName;
                    Debug.Assert(fileName != null, "fileName != null");

                    var destFile = Path.Combine(mDestinationPath, fileName);

                    var fileInfo     = new FileInfo(f.FullPath);
                    var destFileInfo = new FileInfo(destFile);

                    if (destFileInfo.Exists && destFileInfo.LastWriteTimeUtc == fileInfo.LastWriteTimeUtc)
                    {
                        yield return(string.Format("Skipping {0}", fileName));
                    }
                    else
                    {
                        yield return(string.Format("Copying {0} -> {1}", fileName, mDestinationPath));

                        if (!runContext.DryRun)
                        {
                            if (destFileInfo.Exists && (destFileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                            {
                                destFileInfo.Attributes &= ~FileAttributes.ReadOnly;
                            }
                            fileInfo.CopyTo(destFile, true);
                        }
                    }
                }
            }
        }
Exemplo n.º 19
0
        protected override IEnumerable<IComponent> GetComponentsToRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mBranchInfo.BasePath))
            {
                var toSkip = new HashSet<string>(mBranchInfo.ReleasesToSkip, StringComparer.OrdinalIgnoreCase);
                var toDeployDirs = FileUtils.EnumerateDirectories2(mBranchInfo.BasePath, ToDeployRegex.IsMatch);

                foreach (var toDeployDir in toDeployDirs)
                {
                    if (toSkip.Contains(toDeployDir.FileName))
                    {
                        yield return new LogComponent(string.Format("Release '{0}': Skipped", toDeployDir.FileName));
                    }
                    else
                    {
                        yield return new ReleaseComponent(mBranchInfo, toDeployDir.FullPath, mDbConnection);
                    }
                }
            }
        }
Exemplo n.º 20
0
        public IEnumerable<string> Run(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mSourcePath))
            {
                if (!Directory.Exists(mDestinationPath))
                {
                    yield return string.Format("Creating {0}", mDestinationPath);
                    if (!runContext.DryRun)
                        Directory.CreateDirectory(mDestinationPath);
                }

                foreach (var f in FileUtils.EnumerateFiles2(mSourcePath, mFilter))
                {
                    var fileName = f.FileName;
                    Debug.Assert(fileName != null, "fileName != null");

                    var destFile = Path.Combine(mDestinationPath, fileName);

                    var fileInfo = new FileInfo(f.FullPath);
                    var destFileInfo = new FileInfo(destFile);

                    if (destFileInfo.Exists && destFileInfo.LastWriteTimeUtc == fileInfo.LastWriteTimeUtc)
                    {
                        yield return string.Format("Skipping {0}", fileName);
                    }
                    else
                    {
                        yield return string.Format("Copying {0} -> {1}", fileName, mDestinationPath);

                        if (!runContext.DryRun)
                        {
                            if (destFileInfo.Exists && (destFileInfo.Attributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
                            {
                                destFileInfo.Attributes &= ~FileAttributes.ReadOnly;
                            }
                            fileInfo.CopyTo(destFile, true);
                        }
                    }
                }
            }
        }
Exemplo n.º 21
0
        protected override IEnumerable<IComponent> GetComponentsToRun(string action, ComponentRunContext runContext)
        {
            if (runContext.SkipRestore)
            {
                foreach (var databaseInfo in mDatabasesInfos)
                {
                    yield return new LogComponent(string.Format("Restore {0}: Skipped", databaseInfo.Name));
                }
            }
            else
            {
                foreach (var databaseInfo in mDatabasesInfos)
                {
                    yield return new RestoreDatabaseComponent(databaseInfo);
                }
            }

            foreach (var branchInfo in mBranchGraph.GetPath(mBackupBranch, mActiveBranch))
            {
                yield return new BranchComponent(branchInfo, mDatabasesInfos[0].Connection);
            }
        }
            private IEnumerable <string> MakeReleasePackageRun(string action, ComponentRunContext runContext)
            {
                var packageDirectory = runContext.Config.GetPackageDirectory(mReleaseInfo);

                if (Directory.Exists(packageDirectory))
                {
                    yield return(string.Format("Erasing contents of directory {0}", packageDirectory));

                    if (!runContext.DryRun)
                    {
                        FileUtils.DeleteDirectory(packageDirectory);
                    }
                }

                if (!Directory.Exists(packageDirectory))
                {
                    yield return(string.Format("Creating directory {0}", packageDirectory));

                    if (!runContext.DryRun)
                    {
                        Directory.CreateDirectory(packageDirectory);
                    }
                }
            }
        private IEnumerable <string> DeployRun(string action, ComponentRunContext runContext)
        {
            var script = string.Format(@"
USE [master]
ALTER DATABASE [{0}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
RESTORE DATABASE [{0}] FROM  DISK = N'{1}' WITH  FILE = 1,  NOUNLOAD,  STATS = 5
ALTER DATABASE [{0}] SET MULTI_USER
", mDatabaseInfo.Name, mDatabaseInfo.BackupFilePath);

            yield return(string.Format("Restoring {0}", mDatabaseInfo.Name));

            if (!runContext.DryRun)
            {
                using (var process = SqlUtils.SqlCmdExec(mDatabaseInfo.Connection, script))
                {
                    foreach (var processOutputLine in process.GetOutput())
                    {
                        yield return(processOutputLine.Line);
                    }
                }
            }

            yield return("Database restore completed.");
        }
Exemplo n.º 24
0
 protected virtual IComponent GetPostComponent(string action, ComponentRunContext runContext)
 {
     return mLogPost != null ? new LogComponent(mLogPost) : null;
 }
Exemplo n.º 25
0
        private IEnumerable<string> MakeReleasePackageRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mScriptsPath))
            {
                var packageDir = runContext.Config.GetPackageDirectory(mReleaseInfo, "Scripts");
                yield return string.Format("Scripts {0} -> {1}", mScriptsPath, packageDir);

                using (runContext.DepthScope())
                {
                    var synchronizer = new FileSynchronizer(mScriptsPath, packageDir, GetScriptsFilterByEnvironment(runContext.Environment));
                    foreach (var log in synchronizer.Run(action, runContext))
                    {
                        yield return log;
                    }
                }

                var scriptName = mReleaseInfo.Name + @".sql";
                yield return string.Format("Generating script {0}", scriptName);

                var sb = new StringBuilder();
                GenerateScript(runContext.Environment, sb, false, packageDir).RunToEnd();

                if (!runContext.DryRun)
                {
                    File.WriteAllText(runContext.Config.GetPackageDirectory(mReleaseInfo.Branch, scriptName), sb.ToString());
                }
            }
        }
        protected override IEnumerable <IComponent> GetComponentsToRun(string action, ComponentRunContext runContext)
        {
            var graph = new DependencyGraph <IComponent>();

            var prerequisites    = new PrerequisitesComponent(mReleaseInfo);
            var tplComponent     = new TemplatesComponent(mReleaseInfo);
            var reportsComponent = new ReportsComponent(mReleaseInfo);
            var scriptsComponent = new ScriptsComponent(mReleaseInfo, mDbConnection);

            graph.AddDependency(prerequisites, tplComponent);
            graph.AddDependency(prerequisites, reportsComponent);
            graph.AddDependency(prerequisites, scriptsComponent);
            graph.AddDependency(tplComponent, scriptsComponent);
            graph.AddDependency(reportsComponent, scriptsComponent);

            return(graph.GetPath());
        }
Exemplo n.º 27
0
        protected override IEnumerable <IComponent> GetComponentsToRun(string action, ComponentRunContext runContext)
        {
            foreach (var databaseInfo in mDatabasesInfos)
            {
                yield return(new RestoreDatabaseComponent(databaseInfo));
            }

            foreach (var branchInfo in mBranchGraph.GetPath(mBackupBranch, mActiveBranch))
            {
                yield return(new BranchComponent(branchInfo, mDatabasesInfos[0].Connection));
            }
        }
 protected virtual IComponent GetPostComponent(string action, ComponentRunContext runContext)
 {
     return(mLogPost != null ? new LogComponent(mLogPost) : null);
 }
Exemplo n.º 29
0
 protected override IComponent GetPreComponent(string action, ComponentRunContext runContext)
 {
     return new LogComponent(string.Format("Beginning deploy: {0}", runContext.Environment));
 }
Exemplo n.º 30
0
 protected override IComponent GetPreComponent(string action, ComponentRunContext runContext)
 {
     return(new LogComponent(string.Format("Beginning deploy: {0}", runContext.Environment)));
 }
Exemplo n.º 31
0
 public IEnumerable <string> Run(string action, ComponentRunContext runContext)
 {
     yield return(mLog);
 }
Exemplo n.º 32
0
        private bool RunComponent(string action, ComponentRunContext runState)
        {
            Console.WriteLine("[{0:T}] Running '{1}' action", DateTime.Now, action);

            foreach (var log in mRootComponent.Run(action, runState))
            {
                Console.WriteLine("[{0:T}] {1}{2}", DateTime.Now, new string(' ', runState.Depth * 2), log);
                if (runState.Error)
                {
                    Console.WriteLine("[{0:T}] Blocking Errors Detected ):", DateTime.Now);
                    return false;
                }
            }

            Console.WriteLine("\n[{0:T}] Success!\n", DateTime.Now);
            return true;
        }
Exemplo n.º 33
0
        private void RunDeploy(string environment, bool skipRestore)
        {
            Program.Post(() =>
            {
                Console.WriteLine("[{0:T}] Shit's going down!\n", DateTime.Now);
                Beep("start");

                var runState = new ComponentRunContext(mConfiguration, environment, skipRestore);
                if (RunComponent(ActionConstants.Deploy, runState))
                    Beep("success");
                else
                    Beep("error");
            });
        }
        protected override IEnumerable <IComponent> GetComponentsToRun(string action, ComponentRunContext runContext)
        {
            if (Directory.Exists(mBranchInfo.BasePath))
            {
                var toDeployDirs = Directory.EnumerateDirectories(mBranchInfo.BasePath)
                                   .Where(x => ToDeployRegex.IsMatch(Path.GetFileName(x)));

                foreach (var toDeployDir in toDeployDirs)
                {
                    yield return(new ReleaseComponent(mBranchInfo, toDeployDir, mDbConnection));
                }
            }
        }
Exemplo n.º 35
0
 protected abstract IEnumerable<IComponent> GetComponentsToRun(string action, ComponentRunContext runContext);
 protected abstract IEnumerable <IComponent> GetComponentsToRun(string action, ComponentRunContext runContext);
Exemplo n.º 37
0
 public DepthScopeImpl(ComponentRunContext runContext)
 {
     mRunContext = runContext;
     runContext.IncreaseDepth();
 }
Exemplo n.º 38
0
 public IEnumerable<string> Run(string action, ComponentRunContext runContext)
 {
     yield return mLog;
 }