<commit_before>#!/usr/bin/env node

// Overwrite global promise, so GithubApi will use bluebird too.
Promise = require("bluebird");

const fs = require('fs');
const _ = require('lodash');
const http = require('http');
const https = require('https');
const domain = require('domain');
const moment = require('moment-timezone');
const parser = require('commander');
const semver = require('semver');
const { Octokit } = require("@octokit/rest")
const ghauth = Promise.promisify(require('ghauth'));

// Increase number of concurrent requests
http.globalAgent.maxSockets = 30;
https.globalAgent.maxSockets = 30;

// It might be faster to just go through commits on the branch
// instead of iterating over closed issues, look into this later.
//
// Even better yet. I might just be able to do this with git log.
// tags: git log --tags --simplify-by-decoration --format="%ci%n%d"
// prs: git log --grep="Merge pull request #" --format="%s%n%ci%n%b"

// parse cli options
var opts = parser
  .version(require('../package.json').version)
  .requiredOption('-o, --owner <name>', '(required) owner of the Github repository')
  .requiredOption('-r, --repository <name>', '(required) name of the Github repository')
  .option('-d, --data [type]', '(DEPRECATED) use pull requests or commits (choices: pulls, commits)', 'commits')
  .option('-b, --branch [name]', 'name of the default branch', 'master')
  .option('-n, --tag-name [name]', 'tag name for upcoming release', 'upcoming')
  .option('-a, --auth', 'prompt to auth with Github - use this for private repos and higher rate limits')
  .option('-k, --token [token]', 'need to use this or --auth for private repos and higher rate limits')
  .option('-f, --file [name]', 'name of the file to output the changelog to', 'CHANGELOG.md')
  .option('-t, --title [title]', 'title to appear in the top of the changelog', 'Change Log')
  .option('-z, --time-zone [zone]', 'time zone', 'UTC')
  .option('-m, --date-format [format]', 'date format', '(YYYY/MM/DD HH:mm Z)')
  .option('-v, --verbose', 'output details')
  .option('--host [domain]', 'alternate host name to use with github enterprise', 'api.github.com')
  .option('--path-prefix [path]', 'path-prefix for use with github enterprise')
  .option('--between-tags [range]', 'only diff between these two tags, separate by 3 dots ...')
  .option('--issue-body', '(DEPRECATED) include the body of the issue (--data MUST equal \'pulls\')')
  .option('--for-tag [tag]', 'only get changes for this tag')
  .option('--no-merges', 'do not include merges')
  .option('--only-merges', 'only include merges')
  .option('--only-pulls', 'only include pull requests')
  .option('--use-commit-body', 'use the commit body of a merge instead of the message - "Merge branch..."')
  .option('--order-semver', 'use semantic versioning for the ordering instead of the tag date')
  .option('--reverse-changes', 'reverse the order of changes within a release (show oldest first)')
  .option('--hide-tag-names', 'hide tag names in changelog')
  .option('--timeout [milliseconds]', 'Github API timeout', 10000)
  .parse(process.argv);

if (opts.onlyPulls) opts.merges = true;

var betweenTags = [null, null];
var betweenTagsNames = null;
if (opts.betweenTags) betweenTagsNames = opts.betweenTags.split('...');

var forTag = opts.forTag;

var commitsBySha = {}; // populated when calling getAllCommits
var currentDate = moment();

var github = null;

// github auth token
var token = null;

// ~/.config/changelog.json will store the token
var authOptions = {
  clientId   : '<KEY>'
, configName : 'changelog'
, scopes     : ['user', 'public_repo', 'repo']
};

// TODO: Could probably fetch releases so we don't have to get the commit data
// for the sha of each tag to figure out the date. Could save alot on api
// calls.
var getTags = function(){
  var tagOpts = {
    owner: opts.owner
  , repo: opts.repository
  , per_page: 100
  };

  return github.repos.listTags(tagOpts)
    .then(result => result.data)
    .map(function(ref){
      return github.repos.getCommit({
          owner: tagOpts.owner
        , repo: tagOpts.repo
        , ref: ref.commit.sha
      }).then(function({data: commit}){
        opts.verbose && console.log('pulled commit data for tag - ', ref.name);
        var tag = {
            name: ref.name
          , date: moment(commit.commit.committer.date)
        };

        // if betweenTags is specified then
        if (betweenTagsNames && (betweenTagsNames.indexOf(tag.name)>-1)) {
          betweenTags[betweenTagsNames.indexOf(tag.name)] = tag;
        }

        return tag;
      });
    });
};

var _getAllPullRequests = function(page = 1) {<commit_msg>validate tags given in --between-tags option (#93)<commit_after>#!/usr/bin/env node

// Overwrite global promise, so GithubApi will use bluebird too.
Promise = require("bluebird");

const fs = require('fs');
const _ = require('lodash');
const http = require('http');
const https = require('https');
const domain = require('domain');
const moment = require('moment-timezone');
const parser = require('commander');
const semver = require('semver');
const { Octokit } = require("@octokit/rest")
const ghauth = Promise.promisify(require('ghauth'));

// Increase number of concurrent requests
http.globalAgent.maxSockets = 30;
https.globalAgent.maxSockets = 30;

// It might be faster to just go through commits on the branch
// instead of iterating over closed issues, look into this later.
//
// Even better yet. I might just be able to do this with git log.
// tags: git log --tags --simplify-by-decoration --format="%ci%n%d"
// prs: git log --grep="Merge pull request #" --format="%s%n%ci%n%b"

// parse cli options
var opts = parser
  .version(require('../package.json').version)
  .requiredOption('-o, --owner <name>', '(required) owner of the Github repository')
  .requiredOption('-r, --repository <name>', '(required) name of the Github repository')
  .option('-d, --data [type]', '(DEPRECATED) use pull requests or commits (choices: pulls, commits)', 'commits')
  .option('-b, --branch [name]', 'name of the default branch', 'master')
  .option('-n, --tag-name [name]', 'tag name for upcoming release', 'upcoming')
  .option('-a, --auth', 'prompt to auth with Github - use this for private repos and higher rate limits')
  .option('-k, --token [token]', 'need to use this or --auth for private repos and higher rate limits')
  .option('-f, --file [name]', 'name of the file to output the changelog to', 'CHANGELOG.md')
  .option('-t, --title [title]', 'title to appear in the top of the changelog', 'Change Log')
  .option('-z, --time-zone [zone]', 'time zone', 'UTC')
  .option('-m, --date-format [format]', 'date format', '(YYYY/MM/DD HH:mm Z)')
  .option('-v, --verbose', 'output details')
  .option('--host [domain]', 'alternate host name to use with github enterprise', 'api.github.com')
  .option('--path-prefix [path]', 'path-prefix for use with github enterprise')
  .option('--between-tags [range]', 'only diff between these two tags, separate by 3 dots ...')
  .option('--issue-body', '(DEPRECATED) include the body of the issue (--data MUST equal \'pulls\')')
  .option('--for-tag [tag]', 'only get changes for this tag')
  .option('--no-merges', 'do not include merges')
  .option('--only-merges', 'only include merges')
  .option('--only-pulls', 'only include pull requests')
  .option('--use-commit-body', 'use the commit body of a merge instead of the message - "Merge branch..."')
  .option('--order-semver', 'use semantic versioning for the ordering instead of the tag date')
  .option('--reverse-changes', 'reverse the order of changes within a release (show oldest first)')
  .option('--hide-tag-names', 'hide tag names in changelog')
  .option('--timeout [milliseconds]', 'Github API timeout', 10000)
  .parse(process.argv);

if (opts.onlyPulls) opts.merges = true;

var betweenTags = [null, null];
var betweenTagsNames = null;

if (opts.betweenTags) {
  if (!opts.betweenTags.length) {
    return console.error(`Invalid value for --between-tags. Please specify two tags separated by 3 dots ...`);
  }

  betweenTagsNames = opts.betweenTags.split('...');
  if (!betweenTagsNames[0] || !betweenTagsNames[1]) {
    return console.error(`Invalid value for --between-tags. Please specify two tags separated by 3 dots ...`);
  }
}

var forTag = opts.forTag;

var commitsBySha = {}; // populated when calling getAllCommits
var currentDate = moment();

var github = null;

// github auth token
var token = null;

// ~/.config/changelog.json will store the token
var authOptions = {
  clientId   : '<KEY>'
, configName : 'changelog'
, scopes     : ['user', 'public_repo', 'repo']
};

// TODO: Could probably fetch releases so we don't have to get the commit data
// for the sha of each tag to figure out the date. Could save alot on api
// calls.
var getTags = function(){
  var tagOpts = {
    owner: opts.owner
  , repo: opts.repository
  , per_page: 100
  };

  return github.repos.listTags(tagOpts)
    .then(result => result.data)
    .then(tagArray => {
      // check that the tags asked for exist (--between-tags)
      if (betweenTagsNames) {
        const tagNames = tagArray.map(e => e.name);
        if (!tagNames.includes(betweenTagsNames[0])) {
          console.error(`Tag ${betweenTagsNames[0]} was given as a first value of --between-tags but it doesn't exist in repository`);
          process.exit(1);
        }
        if (!tagNames.includes(betweenTagsNames[1])) {
          console.error(`Tag ${betweenTagsNames[1]} was given as a second value of --between-tags but it doesn't exist in repository`);
          process.exit(1);
        }
      }

      return tagArray;
    })
    .map(function(ref){
      return github.repos.getCommit({
          owner: tagOpts.owner
        , repo: tagOpts.repo
        , ref: ref.commit.sha
      }).then(function({data: commit}){
        opts.verbose && console.log('pulled commit data for tag - ', ref.name);
        var tag = {
            name: ref.name
          , date: moment(commit.commit.committer.date)
        };

        // if --between-tags is specified then reference the appropriate tag
        if (betweenTagsNames && (betweenTagsNames.indexOf(tag.name)>-1)) {
          betweenTags[betweenTagsNames.indexOf(tag.name)] = tag;
        }

        return tag;
      });
    });
};

var _getAllPullRequests = function(page = 1) {
{'fraction_non_alphanumeric': 0.15930994602929838, 'fraction_numerical': 0.004047802621434078, 'mean_word_length': 3.391451544646636, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, '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': '705335', 'n_tokens_mistral': 3264, 'n_tokens_neox': 3176, 'n_words': 1068}