예제 #1
0
        private JiraIssuesWriter(JiraOptions opts, Stream outputStream)
        {
            ExcelPackage.LicenseContext = LicenseContext.NonCommercial;

            this._opts = opts;
            this._pkg  = new ExcelPackage(outputStream);
        }
예제 #2
0
        private static void ValidateOptions(JiraOptions options)
        {
            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (string.IsNullOrWhiteSpace(options.JqlQuery))
            {
                throw new ArgumentNullException(nameof(options.JqlQuery));
            }

            if (string.IsNullOrWhiteSpace(options.OutputFilePath))
            {
                throw new ArgumentNullException(nameof(options.OutputFilePath));
            }

            if (options.Logger == null)
            {
                options.Logger = SinkLogger;
            }

            if (options.IsWorkDayPredicate == null)
            {
                options.IsWorkDayPredicate = IsAlwaysWorkDay;
            }
        }
예제 #3
0
        public static async Task <IEnumerable <JiraIssue> > GetIssuesAsync(JiraOptions opts)
        {
            ValidateOptions(opts);

            var awaitableJsonIssues = JiraConnector.GetIssuesAsync(opts);

            opts.ThrowIfCancellationRequested();

            var jsonStatuses = await JiraConnector.GetStatusesAsync(opts);

            opts.ThrowIfCancellationRequested();

            var jsonVersions = await JiraConnector.GetVersionsAsync(opts);

            opts.ThrowIfCancellationRequested();

            var statuses = new JiraStatusCollection(jsonStatuses.Select(j => new JiraStatus(j)));
            var versions = new JiraFixVersionCollection(jsonVersions.Select(j => new JiraFixVersion(j)));
            var issues   = new JiraIssueCollection();

            if (opts.MaxResults.HasValue && opts.MaxResults > 0)
            {
                awaitableJsonIssues = awaitableJsonIssues.Take(opts.MaxResults.Value);
            }

            await foreach (var issue in awaitableJsonIssues)
            {
                opts.ThrowIfCancellationRequested();
                issues.Add(JiraIssueAssembler.Assemble(opts, issue, statuses, versions));
            }

            return(issues);
        }
예제 #4
0
        public static async IAsyncEnumerable <JsonJiraIssue> GetIssuesAsync(JiraOptions opts)
        {
            var urlFormat    = $"/rest/api/2/search?jql={Uri.EscapeDataString(opts.JqlQuery)}&fields={SearchFields}&startAt={{0}}";
            var startAt      = 0;
            var totalFetched = 0;
            var totalYielded = 0;
            var totalYieldedPaddingLength = 0;

            JsonJiraIssuePage jsonIssuePage;

            do
            {
                var jsonStr = await GetStringAsync(string.Format(urlFormat, startAt), opts);

                jsonIssuePage = JsonConvert.DeserializeObject <JsonJiraIssuePage>(jsonStr);
                startAt      += jsonIssuePage.MaxResults;
                totalFetched += jsonIssuePage.Values.Count;

                if (totalYielded == 0)
                {
                    totalYieldedPaddingLength = jsonIssuePage.Total.ToString().Length;
                }

                foreach (var issue in jsonIssuePage.Values)
                {
                    issue.Changelog = await GetChangelog(issue.Key, opts);

                    yield return(issue);

                    totalYielded++;
                    var totalYieldedPadded = totalYielded.ToString().PadLeft(totalYieldedPaddingLength, '0');
                    opts.Logger($"Fetched issue {totalYieldedPadded}/{jsonIssuePage.Total} named {issue.Key}");
                }
            } while (!jsonIssuePage.IsLast && totalFetched < jsonIssuePage.Total);
        }
예제 #5
0
        private static async Task <string> GetStringAsync(string urlStr, JiraOptions opts)
        {
            var encodedUsernamePassword = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{opts.JiraUsername}:{opts.JiraAccessToken}"));

            var httpRequestMessage = new HttpRequestMessage();

            httpRequestMessage.Method                = HttpMethod.Get;
            httpRequestMessage.RequestUri            = new Uri(urlStr, UriKind.Relative);
            httpRequestMessage.Headers.Authorization = new AuthenticationHeaderValue("Basic", encodedUsernamePassword);
            httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

            try
            {
                using (var response = await Client.SendAsync(httpRequestMessage))
                {
                    response.EnsureSuccessStatusCode();

                    using (var responseContent = response.Content)
                    {
                        return(await responseContent.ReadAsStringAsync());
                    }
                }
            }
            catch (Exception ex)
            {
                throw new JiraNetworkException(urlStr, ex);
            }
        }
예제 #6
0
 private JiraIssueAssembler(JiraOptions options, JsonJiraIssue jsonIssue, JiraStatusCollection statuses, JiraFixVersionCollection versions)
 {
     this._options    = options;
     this._jsonIssue  = jsonIssue;
     this._statuses   = statuses;
     this._versions   = versions;
     this._components = new JiraComponentCollection();
     this._issueTypes = new JiraIssueTypeCollection();
     this._issue      = new JiraIssue();
 }
예제 #7
0
        public static async Task <List <JsonJiraStatus> > GetStatusesAsync(JiraOptions opts)
        {
            var jsonStr = await GetStringAsync("/rest/api/2/status", opts);

            var jsonVersions = JsonConvert.DeserializeObject <List <JsonJiraStatus> >(jsonStr);

            opts.Logger($"Fetched {jsonVersions.Count} statuses");

            return(jsonVersions);
        }
예제 #8
0
        public static async Task <List <JsonJiraFixVersion> > GetVersionsAsync(JiraOptions opts)
        {
            var jsonStr = await GetStringAsync($"/rest/api/2/project/{opts.JiraProjectKey}/versions", opts);

            var jsonVersions        = JsonConvert.DeserializeObject <List <JsonJiraFixVersion> >(jsonStr);
            var numericJsonVersions = jsonVersions.Where(IsNumericFixVersion).ToList();

            opts.Logger($"Fetched {numericJsonVersions.Count} fix versions for project {opts.JiraProjectKey}");

            return(numericJsonVersions);
        }
예제 #9
0
        public static async Task Write(JiraOptions opts)
        {
            opts.Logger($"Results will be written to {opts.OutputFilePath}");

            try
            {
                await using var fileStream = File.OpenWrite(opts.OutputFilePath);
                using var serializer       = new JiraIssuesWriter(opts, fileStream);

                var issues = await JiraRepository.GetIssuesAsync(opts);

                serializer.Write(issues);
            }
            catch
            {
                QuietlyDeleteCreatedExcelPackage(opts);
                throw;
            }

            opts.Logger($"Done, exported file can be found at {opts.OutputFilePath}");
        }
예제 #10
0
 public static JiraIssue Assemble(JiraOptions options, JsonJiraIssue jsonIssue, JiraStatusCollection statuses, JiraFixVersionCollection versions)
 {
     return(new JiraIssueAssembler(options, jsonIssue, statuses, versions).Assemble());
 }
예제 #11
0
        private static async Task <List <JsonJiraIssueChangelogEvent> > GetChangelog(string issueKey, JiraOptions opts)
        {
            var urlFormat    = $"/rest/api/2/issue/{issueKey}/changelog?startAt={{0}}";
            var events       = new List <JsonJiraIssueChangelogEvent>();
            var startAt      = 0;
            var totalFetched = 0;

            JsonJiraIssueChangelogPage changelogPage;

            do
            {
                var jsonStr = await GetStringAsync(string.Format(urlFormat, startAt), opts);

                changelogPage = JsonConvert.DeserializeObject <JsonJiraIssueChangelogPage>(jsonStr);
                events.AddRange(changelogPage.Values);
                startAt      += changelogPage.MaxResults;
                totalFetched += changelogPage.Values.Count;
            } while (!changelogPage.IsLast && totalFetched < changelogPage.Total);

            return(events.Where(IsStatusOrFlaggedChangelogItem).OrderBy(e => e.Created).ToList());
        }