js-green-licenses
Version:
JavaScript package.json license checker
165 lines • 6.28 kB
JavaScript
;
// Copyright 2017 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
Object.defineProperty(exports, "__esModule", { value: true });
exports.GitHubRepository = void 0;
// Abstractions over GitHub REST API v3 and related features. For GitHub API,
// see https://developer.github.com/v3/.
const gaxios_1 = require("gaxios");
const path_1 = require("path");
const url_1 = require("url");
function isSingleResponseData(respData) {
return !Array.isArray(respData);
}
function ensureSingleResponseData(respData) {
if (!isSingleResponseData(respData)) {
throw new Error('Expected a single response, got multiple.');
}
return respData;
}
class GitHubRepository {
constructor(owner, repo) {
this.pathPrefix = path_1.posix.join('/repos', owner, repo);
}
getAxiosConfig(authToken) {
return authToken ? { headers: { Authorization: `token ${authToken}` } } : {};
}
async apiGet(path, params) {
const url = new url_1.URL('https://api.github.com');
url.pathname = path_1.posix.join(this.pathPrefix, path);
if (params) {
Object.keys(params).forEach(key => {
url.searchParams.set(key, params[key]);
});
}
const resp = await (0, gaxios_1.request)({
method: 'GET',
url: url.href,
...this.getAxiosConfig(),
});
return resp.data;
}
async apiPost(path, body) {
const url = new url_1.URL('https://api.github.com');
url.pathname = path_1.posix.join(this.pathPrefix, path);
const resp = await (0, gaxios_1.request)({
method: 'POST',
url: url.href,
data: body,
...this.getAxiosConfig(),
});
return resp.data;
}
async getPRCommits(prId, attemptCount = 1) {
let answer = await this.apiGet(path_1.posix.join('pulls', prId.toString()));
answer = ensureSingleResponseData(answer);
if (answer.mergeable === null) {
if (attemptCount > GitHubRepository.MAX_PR_COMMIT_RETRIES) {
throw new Error(`Tried ${attemptCount} times but the mergeable field is not set. Giving up`);
}
console.log('The `mergeable` field is not set yet. Will retry later.');
return new Promise(resolve => {
setTimeout(async () => {
resolve(await this.getPRCommits(prId, attemptCount + 1));
}, 1000);
});
}
else if (!answer.mergeable) {
throw new Error('PR is not mergeable');
}
const mergeCommitSha = answer.merge_commit_sha;
if (!mergeCommitSha) {
throw new Error('Merge commit SHA is not found');
}
const headCommitSha = answer.head && answer.head.sha;
if (!headCommitSha) {
throw new Error('HEAD commit SHA is not found');
}
return { mergeCommitSha, headCommitSha };
}
async createPRReview(prId, commitSha, body) {
await this.apiPost(path_1.posix.join('pulls', prId.toString(), 'reviews'), {
commit_id: commitSha,
body,
event: 'COMMENT',
});
}
async setCommitStatus(commitSha, status, description, context) {
await this.apiPost(path_1.posix.join('statuses', commitSha), {
state: status,
description,
context,
});
}
async getFileContent(commitSha, path) {
let answer;
try {
answer = await this.apiGet(path_1.posix.join('contents', path), {
ref: commitSha,
});
}
catch (_a) {
return null;
}
answer = ensureSingleResponseData(answer);
if (answer.content === undefined) {
throw new Error(`Content of ${path} not found`);
}
const content = Buffer.from(answer.content, 'base64').toString();
return content;
}
async getSinglePackageJson(dir, commitSha) {
const content = await this.getFileContent(commitSha, path_1.posix.join(dir, 'package.json'));
if (!content) {
return null;
}
const filePath = path_1.posix.join('/', dir, 'package.json');
return { filePath, content };
}
async getPackageJsonFiles(commitSha) {
const packageJsons = [];
// Find the top-level package.json first.
const pj = await this.getSinglePackageJson('', commitSha);
if (pj !== null) {
packageJsons.push(pj);
}
// Find `packages/<name>/package.json` files in case this is a monorepo.
let answer;
try {
answer = await this.apiGet('contents/packages', { ref: commitSha });
}
catch (_a) {
// Not a monorepo. Return just the top-level package.json.
return packageJsons;
}
if (!isSingleResponseData(answer)) {
// Response is an array, which means there's the `packages` directory and
// this is a monorepo. Find package.json from each directory under
// `packages`.
for (const entry of answer) {
if (entry.type === 'dir' && entry.name) {
const pj = await this.getSinglePackageJson(path_1.posix.join('packages', entry.name), commitSha);
if (pj !== null) {
packageJsons.push(pj);
}
}
}
}
return packageJsons;
}
}
exports.GitHubRepository = GitHubRepository;
// How many times to retry PR commit retrieval until giving up.
GitHubRepository.MAX_PR_COMMIT_RETRIES = 10;
//# sourceMappingURL=github.js.map