Example #1
0
        // To simplify things, the initial report uses constants.
        // TODO Add command line args to allow the user to change things, or set this up with some sort of GUI.
        // TODO Refactor so this isn't a monolithic method.
        public static async Task Main(string[] args)
        {
            Console.WriteLine(Strings.About);

            if (args.Any(p => p.Equals("clear", StringComparison.InvariantCultureIgnoreCase)))
            {
                SecretsManager.Clear();
            }

            // Check for and collect credentials.
            if (!TryGetCredentials(out var userName, out var userToken))
            {
                return;
            }

            // Check for and create the output directory.
            var outputPath = TryCreateOutputDirectory(GitHubConstants.DefaultOutputRoot);

            if (outputPath is null)
            {
                return;
            }

            // Test the credentials.
            var nameToGet = "bot-docs";
            var repo      = GitHubConstants.KnownRepos.FirstOrDefault(
                r => r.Name.Equals(nameToGet, StringComparison.InvariantCultureIgnoreCase));

            if (repo is null)
            {
                Console.WriteLine($"Sorry, The '{nameToGet}' repo is not defined in the constants file; exiting.");
                return;
            }

            Console.WriteLine("Testing your user token...");
            try
            {
                var data = await GitHubQlService.ExecuteGraphQLRequest(Requests.GetUserInfo(userName));

                //await GitHubGraphQlService.Queries
                //    .GetUser(userName).ConfigureAwait(false);
                Console.WriteLine(data.User.ForConsole());
            }
            catch (Exception ex)
            {
                Console.WriteLine($"{ex.GetType().Name} encountered: {ex.Message}...exiting.");
                return;
            }
            Console.WriteLine();

            // Generate a simple bot-docs report summarizing the contents of the repo.
            var summaryHelper = new RepoHelper(Now);
            var query         = Requests.GetRepository(repo);
            var rData         = await GitHubQlService.ExecuteGraphQLRequest(query);

            var repoReport = Path.Combine(outputPath, "Repository.csv");

            Console.Write($"Writing general information about the repository to '{repoReport}'...");
            using (TextWriter writer = new StreamWriter(repoReport, false))
            {
                writer.WriteLine(string.Join(',', summaryHelper.DefaultFormatter.Keys));
                writer.WriteLine(string.Join(',',
                                             summaryHelper.DefaultFormatter.Values.Select(func => func(rData.Repository)?.CsvEscape() ?? string.Empty)));
            }
            Console.WriteLine("done.");
            Console.WriteLine();

            // Generate an issues report against the bot-docs repo.
            var issueHelper = new IssueHelper(Now);

            await GetDocRepoIssues(repo, outputPath, issueHelper.DefaultFormatter);

            // Generate report for open doc issues in the code repos.
            var filePath    = Path.Combine(outputPath, "CodeRepoIssues.csv");
            var repos       = GitHubConstants.KnownRepos.Where(r => RepoIsOfType(r, GitHubConstants.RepoTypes.Code));
            var stateFilter = new IssueState[] { IssueState.OPEN };
            var labelFilter = new string[] { "documentation", "Docs", "DCR" };

            await GenerateIssuesReport(repos, issueHelper.DefaultFormatter, filePath, stateFilter, labelFilter);

            // Generate an issues report against the botframework-solutions repo.
            filePath = Path.Combine(outputPath, "SlaIssuesReport.csv");
            repos    = GitHubConstants.KnownRepos.Where(r => r.Name.Equals("botframework-solutions", StringComparison.CurrentCultureIgnoreCase));
            await GenerateIssuesReport(repos, issueHelper.DefaultFormatter, filePath, null, null);

            //filePath = Path.Combine(outputPath, "DocRepoIssues.csv");
            //repos = GitHubConstants.KnownRepos.Where(r => RepoIsOfType(r, GitHubConstants.RepoTypes.Docs | GitHubConstants.RepoTypes.Private));

            //await GenerateIssuesReport(repos, issueFormatter, filePath);

            //var taClient = new TextAnalyticsService("westus2");

            //// The "documents" to analyze. These mat need to be batched. Review
            //// [Text Analytics Overview > Data limits](https://docs.microsoft.com/en-us/azure/cognitive-services/text-analytics/overview#data-limits).
            //var input = issues.Select(i => new MultiLanguageInput("en", i.Number.ToString(), i.BodyText)).ToList();

            //// Once we're done, this will be the aggregated output from analysis.
            //var output = new List<SentimentBatchResultItem>();

            //// TODO track what we've already analyzed, so that:
            //// 1. We don't reanalyze the same issue twice.
            //// 1. We can sanely add to the existing data set.

            //var docData = new CognitiveServicesDocData
            //{
            //    Docs = issues.Select(i => new CognitiveServicesDoc
            //    {
            //        Language = "en",
            //        Id = i.Number.ToString(),
            //        Text = i.Body,
            //    }).ToList(),
            //};
            //// TODO Make the call(s) to the Text Analytics service, aggregate results, generate a report.
            //Console.WriteLine();

            // Other reports that might be useful:
            // - Issues in other repos that have the "Docs" label applied.
            // - PRs in the main code repos that are labeled as "DCR".
            // - Merge activity in the samples repo.
            // - An orphaned or stale branch report for bot-docs-pr.

            // Any reports that crawl the file content may be better suited to the other tool:
            // - Topics that need review, such as their ms.date attribute is getting old, the author
            //   or manager is no longer on the team, or any other metadata maintenance we might need to do.
        }