diff --git a/.babelrc b/.babelrc new file mode 100644 index 00000000..73fd93a2 --- /dev/null +++ b/.babelrc @@ -0,0 +1,12 @@ +{ + presets: [ + 'react', + 'env', + ], + plugins: [ + 'react-require', + 'transform-object-rest-spread', + 'transform-class-properties', + 'babel-plugin-inline-import', + ], +} diff --git a/package-lock.json b/package-lock.json index 87d646e6..af6e3e75 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1042,6 +1042,17 @@ "babel-template": "6.26.0" } }, + "babel-inline-import-loader": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/babel-inline-import-loader/-/babel-inline-import-loader-0.1.0.tgz", + "integrity": "sha1-994/LWzK1Y1lEGAiPpyI6IpwKcU=", + "dev": true, + "requires": { + "babel-traverse": "6.26.0", + "babel-types": "6.26.0", + "babylon": "6.18.0" + } + }, "babel-loader": { "version": "7.1.5", "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.5.tgz", @@ -1086,6 +1097,15 @@ "estraverse": "4.2.0" } }, + "babel-plugin-inline-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-inline-import/-/babel-plugin-inline-import-3.0.0.tgz", + "integrity": "sha512-thnykl4FMb8QjMjVCuZoUmAM7r2mnTn5qJwrryCvDv6rugbJlTHZMctdjDtEgD0WBAXJOLJSGXN3loooEwx7UQ==", + "dev": true, + "requires": { + "require-resolve": "0.0.2" + } + }, "babel-plugin-react-require": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/babel-plugin-react-require/-/babel-plugin-react-require-3.0.0.tgz", @@ -13372,6 +13392,12 @@ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", "dev": true }, + "path-extra": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/path-extra/-/path-extra-1.0.3.tgz", + "integrity": "sha1-fBEhiablDVlXkOetIDfkTkEMEWY=", + "dev": true + }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", @@ -14917,6 +14943,15 @@ "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", "dev": true }, + "require-resolve": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/require-resolve/-/require-resolve-0.0.2.tgz", + "integrity": "sha1-urQQqxruLz9Vt5MXRR3TQodk5vM=", + "dev": true, + "requires": { + "x-path": "0.0.2" + } + }, "require-uncached": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", @@ -18571,6 +18606,15 @@ "readable-stream": "0.0.4" } }, + "x-path": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/x-path/-/x-path-0.0.2.tgz", + "integrity": "sha1-KU0Ha7l6dwbMBwu7Km/YxU32exI=", + "dev": true, + "requires": { + "path-extra": "1.0.3" + } + }, "xdg-basedir": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", diff --git a/package.json b/package.json index ebe8ab4e..2e4d2e4e 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,9 @@ "babel-cli": "^6.26.0", "babel-core": "^6.3.17", "babel-eslint": "^7.1.0", + "babel-inline-import-loader": "^0.1.0", "babel-loader": "^7.0.0", + "babel-plugin-inline-import": "^3.0.0", "babel-plugin-react-require": "^3.0.0", "babel-plugin-transform-class-properties": "^6.24.1", "babel-plugin-transform-object-rest-spread": "^6.26.0", diff --git a/script/build.sh b/script/build.sh index d3d44bd8..7a7d47fb 100755 --- a/script/build.sh +++ b/script/build.sh @@ -3,4 +3,4 @@ set -e -x npm run build -NODE_ENV=development npx babel-node --presets env --plugins transform-class-properties script/fetch-issues.js +NODE_ENV=development npx babel-node script/fetch-issues.js diff --git a/script/queries/export.js b/script/queries/export.js deleted file mode 100644 index f5862ce8..00000000 --- a/script/queries/export.js +++ /dev/null @@ -1,4 +0,0 @@ -export { GITHUB_ISSUE_INFO_QUERY } from './github_issue_info'; -export { GITHUB_PR_INFO_QUERY } from './github_pr_info'; -export { GITHUB_LABEL_INFO_QUERY } from './github_label_info'; -export { GITHUB_REACTION_INFO_QUERY } from './github_reaction_info'; diff --git a/script/queries/github_issue_info.graphql b/script/queries/github_issue_info.graphql index f81d3b56..73d2200a 100644 --- a/script/queries/github_issue_info.graphql +++ b/script/queries/github_issue_info.graphql @@ -1,6 +1,11 @@ -query($owner: String!, $name: String!, $before: String) { +query($owner: String!, $name: String!, $perPage: Int!, $before: String, $orderBy: IssueOrder!) { + rateLimit { + limit + remaining + resetAt + } repository(owner:$owner, name:$name) { - issues(last:100, before:$before) { + issues(last:$perPage, before:$before, orderBy:$orderBy) { pageInfo { startCursor hasPreviousPage diff --git a/script/queries/github_issue_info.js b/script/queries/github_issue_info.js deleted file mode 100644 index c3b8d578..00000000 --- a/script/queries/github_issue_info.js +++ /dev/null @@ -1,53 +0,0 @@ -export const GITHUB_ISSUE_INFO_QUERY = ` - query($owner: String!, $name: String!, $perPage: Int!, $before: String, $orderBy: IssueOrder!) { - rateLimit { - limit - remaining - resetAt - } - repository(owner:$owner, name:$name) { - issues(last:$perPage, before:$before, orderBy:$orderBy) { - pageInfo { - startCursor - hasPreviousPage - } - nodes { - title - bodyText - url - number - state - comments { - totalCount - } - milestone { - title - createdAt - dueOn - state - url - description - } - createdAt - updatedAt - closedAt - author { - login - avatarUrl - } - assignees(first:1) { - nodes { - login - avatarUrl - } - } - labels(first:100) { - nodes { - color - name - } - } - } - } - } - }`; diff --git a/script/queries/github_label_info.graphql b/script/queries/github_label_info.graphql index db42626e..4378573b 100644 --- a/script/queries/github_label_info.graphql +++ b/script/queries/github_label_info.graphql @@ -1,4 +1,9 @@ query($owner: String!, $name: String!) { + rateLimit { + limit + remaining + resetAt + } repository(owner:$owner, name:$name) { labels(first:100){ nodes { diff --git a/script/queries/github_label_info.js b/script/queries/github_label_info.js deleted file mode 100644 index 551a0d9e..00000000 --- a/script/queries/github_label_info.js +++ /dev/null @@ -1,19 +0,0 @@ -export const GITHUB_LABEL_INFO_QUERY = ` - query($owner: String!, $name: String!) { - rateLimit { - limit - remaining - resetAt - } - repository(owner:$owner, name:$name) { - labels(first:100){ - nodes { - id - url - name - color - isDefault - } - } - } - }`; diff --git a/script/queries/github_pr_info.graphql b/script/queries/github_pr_info.graphql index 6d8da6af..768f3aaa 100644 --- a/script/queries/github_pr_info.graphql +++ b/script/queries/github_pr_info.graphql @@ -1,6 +1,11 @@ -query($owner: String!, $name: String!, $before: String) { +query($owner: String!, $name: String!, $perPage: Int!, $before: String, $orderBy: IssueOrder!) { + rateLimit { + limit + remaining + resetAt + } repository(owner:$owner, name:$name) { - pullRequests(last:30, before:$before) { + pullRequests(last:$perPage, before:$before, orderBy:$orderBy) { pageInfo { startCursor hasPreviousPage diff --git a/script/queries/github_pr_info.js b/script/queries/github_pr_info.js deleted file mode 100644 index 57445789..00000000 --- a/script/queries/github_pr_info.js +++ /dev/null @@ -1,98 +0,0 @@ -export const GITHUB_PR_INFO_QUERY = ` - query($owner: String!, $name: String!, $perPage: Int!, $before: String, $orderBy: IssueOrder!) { - rateLimit { - limit - remaining - resetAt - } - repository(owner:$owner, name:$name) { - pullRequests(last:$perPage, before:$before, orderBy:$orderBy) { - pageInfo { - startCursor - hasPreviousPage - } - nodes { - title - bodyText - url - number - state - reviews(first: 20) { - totalCount - nodes { - comments(first: 100) { - totalCount - nodes { - id - url - bodyText - diffHunk - createdAt - lastEditedAt - author { - login - avatarUrl - ... on User { - name - } - } - reactionGroups { - content - createdAt - } - } - } - } - } - comments(first:100) { - totalCount - nodes { - id - url - bodyText - createdAt - lastEditedAt - author { - login - avatarUrl - ... on User { - name - } - } - reactionGroups { - content - createdAt - } - } - } - milestone { - title - createdAt - dueOn - state - url - description - } - createdAt - updatedAt - closedAt - author { - login - avatarUrl - } - assignees(first:1) { - nodes { - login - avatarUrl - } - } - labels(first:100) { - nodes { - color - name - } - } - } - } - } - }`; diff --git a/script/queries/github_reaction_info.graphql b/script/queries/github_reaction_info.graphql index aaa7493e..900b3b1e 100644 --- a/script/queries/github_reaction_info.graphql +++ b/script/queries/github_reaction_info.graphql @@ -1,10 +1,15 @@ query($owner: String!, $name: String!, $number: Int!, - $reviewCnt: Int!, $maxCommentsPerReview: Int!, $commentCnt: Int!) { + $reviewsCount: Int!, $discussionsPerReview: Int!, $commentsCount: Int!) { + rateLimit { + limit + remaining + resetAt + } repository(owner:$owner, name:$name) { pullRequest(number: $number) { - reviews(first: $reviewCnt) { + reviews(first: $reviewsCount) { nodes { - comments(first: $maxCommentsPerReview) { + comments(first: $discussionsPerReview) { nodes { id reactions(first: 100) { @@ -22,7 +27,7 @@ query($owner: String!, $name: String!, $number: Int!, } } } - comments(first:$commentCnt) { + comments(first:$commentsCount) { nodes { id reactions(first: 100) { diff --git a/script/queries/github_reaction_info.js b/script/queries/github_reaction_info.js deleted file mode 100644 index 7dd2e196..00000000 --- a/script/queries/github_reaction_info.js +++ /dev/null @@ -1,49 +0,0 @@ -export const GITHUB_REACTION_INFO_QUERY = ` - query($owner: String!, $name: String!, $number: Int!, - $reviewsCount: Int!, $discussionsPerReview: Int!, $commentsCount: Int!) { - rateLimit { - limit - remaining - resetAt - } - repository(owner:$owner, name:$name) { - pullRequest(number: $number) { - reviews(first: $reviewsCount) { - nodes { - comments(first: $discussionsPerReview) { - nodes { - id - reactions(first: 100) { - nodes { - id - createdAt - content - user { - login - name - } - } - } - } - } - } - } - comments(first:$commentsCount) { - nodes { - id - reactions(first: 100) { - nodes { - id - createdAt - content - user { - login - name - } - } - } - } - } - } - } - }`; diff --git a/script/queries/index.js b/script/queries/index.js index 937a7be7..f95d3544 100644 --- a/script/queries/index.js +++ b/script/queries/index.js @@ -1,8 +1,10 @@ -const fs = require('fs'); -const loadQuery = name => - fs.readFileSync(`${__dirname}/${name}.graphql`).toString(); - -module.exports.GITHUB_ISSUE_INFO_QUERY = loadQuery('github_issue_info'); -module.exports.GITHUB_PR_INFO_QUERY = loadQuery('github_pr_info'); -module.exports.GITHUB_LABEL_INFO_QUERY = loadQuery('github_label_info'); -module.exports.GITHUB_REACTION_INFO_QUERY = loadQuery('github_reaction_info'); +import GITHUB_ISSUE_INFO_QUERY from './github_issue_info.graphql'; +import GITHUB_PR_INFO_QUERY from './github_pr_info.graphql'; +import GITHUB_LABEL_INFO_QUERY from './github_label_info.graphql'; +import GITHUB_REACTION_INFO_QUERY from './github_reaction_info.graphql'; +export { + GITHUB_ISSUE_INFO_QUERY, + GITHUB_PR_INFO_QUERY, + GITHUB_LABEL_INFO_QUERY, + GITHUB_REACTION_INFO_QUERY +}; diff --git a/src/github-graphql.js b/src/github-graphql.js index 33f8d46e..e8305617 100644 --- a/src/github-graphql.js +++ b/src/github-graphql.js @@ -6,7 +6,7 @@ import { GITHUB_PR_INFO_QUERY, GITHUB_LABEL_INFO_QUERY, GITHUB_REACTION_INFO_QUERY, -} from '../script/queries/export'; +} from '../script/queries'; const DEBUG = process.env.NODE_ENV === 'development'; @@ -154,6 +154,7 @@ class GraphQLClient { this.cursor = null; this.pageCount = 0; this.fetchedData = null; + this.warningCount = 0; if (this._fetch === this._fetchLabels || this._fetch === this._fetchReactions) { @@ -165,8 +166,6 @@ class GraphQLClient { // fetch data with pagination this.pagination = true; while (this.pagination) { - // clear warning count before every fresh fetch - this.warningCount = 0; await this._fetch(this.cursor); } if (DEBUG) { @@ -324,9 +323,9 @@ class GraphQLClient { this.fetchedData = []; } - // if result === [null], skip it - if (result && result.length && result[0]) { - this.fetchedData = this.fetchedData.concat(result); + if (result && result.length) { + // filter out null element + this.fetchedData = this.fetchedData.concat(result.filter((elem) => elem)); } if (!hasPreviousPage || reachDateThreshold) { @@ -412,7 +411,8 @@ class GraphQLClient { const commentsCount = Math.min(node.comments.totalCount, 100); const commentsWithReactions = await new GraphQLClient(this.token, - this.sleepTime, this.emitter, 3) + this.ignoreAuthor, this.ignoreContent, + this.emitter, this.sleepTime, 3) .repo(this.repoOwner, this.repoName) .reactions({pr_number: number, reviews_count: reviewsCount, @@ -496,9 +496,9 @@ class GraphQLClient { this.fetchedData = []; } - // if result === [null], skip it - if (result && result.length && result[0]) { - this.fetchedData = this.fetchedData.concat(result); + if (result && result.length) { + // filter out null element + this.fetchedData = this.fetchedData.concat(result.filter((elem) => elem)); } if (!hasPreviousPage || reachDateThreshold) { @@ -573,12 +573,6 @@ class GraphQLClient { return result; } - _updateRateLimit(rateLimit) { - this.remaining = rateLimit.remaining; - this.limit = rateLimit.limit; - this.resetAt = rateLimit.resetAt; - } - _slowStart() { // strategy to save API limit and network bandwidth // a common senario of the client is to sync updated issues/prs @@ -603,8 +597,8 @@ class GraphQLClient { } else { console.log('warning count:', warningCount, 'reaches warning threshold', this.warningThreshold, 'stop fetching'); - // reset warning count - this.warningCount = 0; + // stop pagination, if any + this.pagination = false; } } } diff --git a/webpack.config.js b/webpack.config.js index 7bd1bc4d..db4600a4 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -24,20 +24,10 @@ module.exports = { { test: /\.jsx?$/, exclude: [/node_modules/, /octokat\.js/], - use: { - loader: 'babel-loader', - options: { - presets: [ - 'react', - 'env' - ], - plugins: [ - 'react-require', - 'transform-object-rest-spread', - 'transform-class-properties' - ], - } - }, + use: [ + 'babel-inline-import-loader', + 'babel-loader', + ] }, { test: /\.less$/,