index.js (3932B)
1 #!/usr/bin/env node 2 /* jshint esversion: 6 */ 3 4 const program = require("commander"); 5 const co = require("co"); 6 const prompt = require("co-prompt"); 7 const { Octokit } = require("@octokit/rest"); 8 const { throttling } = require("@octokit/plugin-throttling"); 9 const { importFile } = require("./import.js"); 10 const { exportIssues } = require("./export.js"); 11 12 program 13 .version(require("../package.json").version) 14 .arguments("[file]") 15 .option( 16 "-g, --github_enterprise [https://api.github.my-company.com]", 17 "Your GitHub Enterprise URL." 18 ) 19 .option( 20 "-t, --token [token]", 21 "The GitHub token. https://github.com/settings/tokens" 22 ) 23 .option( 24 "-o, --organization [organization]", 25 "The User or Organization slug that the repo lives under." 26 ) 27 .option("-r, --repository [repository]", "The repository name (slug).") 28 .option( 29 "-f, --exportFileName [export.csv]", 30 "The name of the CSV you'd like to export to." 31 ) 32 .option( 33 "-a, --exportAttributes [attributes]", 34 "Comma-separated list of attributes (columns) in the export." 35 ) 36 .option("-c, --exportComments", "Include comments in the export.") 37 .option("-e, --exportAll", "Include all data in the export.") 38 .option( 39 "--csvDelimiter [csvDelimiter]", 40 "CSV delimiter character (defaults to ',')" 41 ) .option("-v, --verbose", "Include additional logging information.") 42 .action(function (file, options) { 43 co(function* () { 44 const retObject = {}; 45 retObject.githubUrl = 46 options.github_enterprise || "https://api.github.com"; 47 retObject.token = options.token || ""; 48 if (retObject.token === "") { 49 retObject.token = yield prompt( 50 "Token (get from https://github.com/settings/tokens): " 51 ); 52 } 53 retObject.exportFileName = options.exportFileName || false; 54 retObject.exportAttributes = options.exportAttributes || false; 55 if (retObject.exportAttributes) { 56 retObject.exportAttributes = retObject.exportAttributes 57 .split(",") 58 .map((i) => i.trim()); 59 } 60 retObject.exportComments = options.exportComments || false; 61 retObject.exportAll = options.exportAll || false; 62 retObject.csvDelimiter = options.csvDelimiter || ','; 63 retObject.verbose = options.verbose || false; 64 65 retObject.userOrOrganization = options.organization || ""; 66 if (retObject.userOrOrganization === "") { 67 retObject.userOrOrganization = yield prompt("User or organization: "); 68 } 69 70 retObject.repo = options.repository || ""; 71 if (retObject.repo === "") { 72 retObject.repo = yield prompt("Repository: "); 73 } 74 return retObject; 75 }).then( 76 function (values) { 77 const ThrottledOctokit = Octokit.plugin(throttling); 78 const octokit = new ThrottledOctokit({ 79 auth: values.token, 80 userAgent: "github-csv-tools", 81 baseUrl: values.githubUrl, 82 throttle: { 83 onRateLimit: (retryAfter, options) => { 84 console.warn( 85 `Request quota exhausted for request ${options.method} ${options.url}` 86 ); 87 88 if (options.request.retryCount === 0) { 89 // only retries once 90 console.log(`Retrying after ${retryAfter} seconds!`); 91 return true; 92 } 93 }, 94 onAbuseLimit: (retryAfter, options) => { 95 // does not retry, only logs a warning 96 console.warn( 97 `Abuse detected for request ${options.method} ${options.url}` 98 ); 99 }, 100 }, 101 }); 102 103 if (file) { 104 // This is an import! 105 importFile(octokit, file, values); 106 } else { 107 // this is an export! 108 exportIssues(octokit, values); 109 } 110 }, 111 function (err) { 112 console.error("ERROR", err); 113 } 114 ); 115 }) 116 .parse(process.argv);