<commit_before>using System;
using System.Collections.Generic;
using System.Linq;
using ManyConsole;
using NDesk.Options;
using TeamCityBuildChanges.ExternalApi.Jira;
using TeamCityBuildChanges.ExternalApi.TFS;
using TeamCityBuildChanges.ExternalApi.TeamCity;
using TeamCityBuildChanges.IssueDetailResolvers;
using TeamCityBuildChanges.Output;

namespace TeamCityBuildChanges.Commands
{
    internal class TeamCityCommandBase : ConsoleCommand
    {
        protected bool NoVersion;
        protected Boolean Xml;
        protected string OutputFileName;
        protected List<ChangeDetail> ChangeDetails;
        protected List<Issue> IssueDetails;
        protected ChangeManifest ChangeManifest = new ChangeManifest();
        protected string ServerName;
        protected string BuildType;
        protected string ProjectName;
        protected string BuildName;
        protected string JiraUrl;
        protected string JiraToken;
        protected string TfsUrl;
        protected string Template;

        public TeamCityCommandBase()
        {
            Options = new OptionSet
                {
                    {"noversion|nv", "Don't include the version in the output of the change details, instead use a *", v => NoVersion = true},
                    {"x|xmloutput", "OutputFileName to XML", x => Xml = true},
                    {"o|output=", "OutputFileName filename (otherwise to console)", x => OutputFileName = x},
                    {"b=|buildType=", "TeamCity build type to get the details for.", s => BuildType = s},
                    {"p=|project=", "TeamCity project to search within for specific build name.", s => ProjectName = s},
                    {"bn=|buildName=", "TeamCity build type to get the details for.", s => BuildName = s},
                    {"jiraurl=", "The Jira URL to query for issue details", x => JiraUrl = x},
                    {"jiraauthtoken=", "The Jira authorisation token to use (refer to 'encode' subcommand", x => JiraToken = x},
                    {"tfsurl=", "TFS URL to check issues on.", x => TfsUrl = x},
                    {"template=", "Template to use for output.  Must be a Razor template that accepts a ChangeManifest model.", x => Template = x}
                };

            HasRequiredOption("s|server=", "TeamCity server to target (just use base URL and have guestAuth enabled", s => ServerName = s);
        }

        public override int Run(string[] remainingArguments)
        {
            return 0;
        }

        protected void OutputChanges(IEnumerable<IOutputRenderer> renderers, IEnumerable<Action<string>> writers)
        {
            var enumerable = writers as List<Action<string>> ?? writers.ToList();
            foreach (var renderer in renderers)
            {
                foreach (var writer in enumerable)
                {
                    writer(renderer.Render(ChangeManifest));
                }
            }
        }

        protected IEnumerable<IExternalIssueResolver> CreateExternalIssueResolvers()
        {
            var resolvers = new List<IExternalIssueResolver>();

            if (string.IsNullOrEmpty(JiraToken))
            {
                Uri cleanUri;
                JiraToken = new Uri(JiraUrl).TryResolveAuthToken(out cleanUri);
            }

            if (!string.IsNullOrEmpty(JiraToken) && !string.IsNullOrEmpty(JiraUrl))
            {
                resolvers.Add(new JiraIssueResolver(new JiraApi(JiraUrl, JiraToken)));
            }
            if (!string.IsNullOrEmpty(TfsUrl))
            {
                resolvers.Add(new TFSIssueResolver(new TfsApi(TfsUrl)));
            }
            return resolvers;
        }

        protected IEnumerable<IOutputRenderer> CreateOutputRenderers()
        {
            var renderers = new List<IOutputRenderer>
                {
                    string.IsNullOrEmpty(Template) ? new RazorOutputRenderer() : new RazorOutputRenderer(Template)
                };

            return renderers;
        }
    }<commit_msg>Remove check for JIRA auth token in CreateExternalIssueResolvers, should be handled in RestClient.  Do we still need the EncodeCommand?<commit_after>using System;
using System.Collections.Generic;
using System.Linq;
using ManyConsole;
using NDesk.Options;
using TeamCityBuildChanges.ExternalApi.Jira;
using TeamCityBuildChanges.ExternalApi.TFS;
using TeamCityBuildChanges.ExternalApi.TeamCity;
using TeamCityBuildChanges.IssueDetailResolvers;
using TeamCityBuildChanges.Output;

namespace TeamCityBuildChanges.Commands
{
    internal class TeamCityCommandBase : ConsoleCommand
    {
        protected bool NoVersion;
        protected Boolean Xml;
        protected string OutputFileName;
        protected List<ChangeDetail> ChangeDetails;
        protected List<Issue> IssueDetails;
        protected ChangeManifest ChangeManifest = new ChangeManifest();
        protected string ServerName;
        protected string BuildType;
        protected string ProjectName;
        protected string BuildName;
        protected string JiraUrl;
        protected string JiraToken;
        protected string TfsUrl;
        protected string Template;

        public TeamCityCommandBase()
        {
            Options = new OptionSet
                {
                    {"noversion|nv", "Don't include the version in the output of the change details, instead use a *", v => NoVersion = true},
                    {"x|xmloutput", "OutputFileName to XML", x => Xml = true},
                    {"o|output=", "OutputFileName filename (otherwise to console)", x => OutputFileName = x},
                    {"b=|buildType=", "TeamCity build type to get the details for.", s => BuildType = s},
                    {"p=|project=", "TeamCity project to search within for specific build name.", s => ProjectName = s},
                    {"bn=|buildName=", "TeamCity build type to get the details for.", s => BuildName = s},
                    {"jiraurl=", "The Jira URL to query for issue details", x => JiraUrl = x},
                    {"jiraauthtoken=", "The Jira authorisation token to use (refer to 'encode' subcommand", x => JiraToken = x},
                    {"tfsurl=", "TFS URL to check issues on.", x => TfsUrl = x},
                    {"template=", "Template to use for output.  Must be a Razor template that accepts a ChangeManifest model.", x => Template = x}
                };

            HasRequiredOption("s|server=", "TeamCity server to target (just use base URL and have guestAuth enabled", s => ServerName = s);
        }

        public override int Run(string[] remainingArguments)
        {
            return 0;
        }

        protected void OutputChanges(IEnumerable<IOutputRenderer> renderers, IEnumerable<Action<string>> writers)
        {
            var enumerable = writers as List<Action<string>> ?? writers.ToList();
            foreach (var renderer in renderers)
            {
                foreach (var writer in enumerable)
                {
                    writer(renderer.Render(ChangeManifest));
                }
            }
        }

        protected IEnumerable<IExternalIssueResolver> CreateExternalIssueResolvers()
        {
            var resolvers = new List<IExternalIssueResolver>();

            if (!string.IsNullOrEmpty(JiraUrl))
            {
                resolvers.Add(new JiraIssueResolver(new JiraApi(JiraUrl, JiraToken)));
            }
            if (!string.IsNullOrEmpty(TfsUrl))
            {
                resolvers.Add(new TFSIssueResolver(new TfsApi(TfsUrl)));
            }
            return resolvers;
        }

        protected IEnumerable<IOutputRenderer> CreateOutputRenderers()
        {
            var renderers = new List<IOutputRenderer>
                {
                    string.IsNullOrEmpty(Template) ? new RazorOutputRenderer() : new RazorOutputRenderer(Template)
                };

            return renderers;
        }
    }
{'fraction_non_alphanumeric': 0.08731756416708605, 'fraction_numerical': 0.0002516356316054353, 'mean_word_length': 2.1593799682034978, 'pattern_counts': {'":': 0, '<': 25, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3866085', 'n_tokens_mistral': 2001, 'n_tokens_neox': 1948, 'n_words': 589}