Created
October 7, 2019 15:52
-
-
Save rcebulko/1bdc4086f8bf3e97a3119d0d9b7cf95e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Copyright 2019 The AMP HTML Authors. | |
* | |
* 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 | |
* | |
* http://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. | |
*/ | |
/** | |
* @fileoverview | |
* The owners bot project was started with YAML as the file syntax, and later | |
* the decision was made to transition to JSON5 (see https://json5.org). While | |
* the parser supports both versions, this purpose of this script is to parse an | |
* existing OWNERS.yaml file and output the same owners rules in JSON5 format. | |
* This script will swallow all comments, so any comments that need to be | |
* transferred from the YAML files must be copied manually. | |
*/ | |
const JSON5 = require('json5'); | |
const fs = require('fs'); | |
const {Team} = require('../src/github'); | |
const {OWNER_MODIFIER} = require('../src/owner'); | |
const {PatternOwnersRule, SameDirPatternOwnersRule} = require('../src/rules'); | |
const {LocalRepository} = require('../src/local_repo'); | |
const {OwnersParser} = require('../src/parser'); | |
const FILE_COMMENT = | |
'// For an explanation of the OWNERS rules and syntax, see:\n' + | |
'// https://github.com/ampproject/amp-github-apps/blob/master/owners/OWNERS.example'; | |
// Absolute path to local repository root directory. Passed as a command-line | |
// argument, ie. `node yaml_to_json.js /foo/amphtml` | |
const GITHUB_REPO_DIR = process.argv[2]; | |
// The parser uses a map of teams to determine which teams are valid; to reduce | |
// the complexity of this script since it's a one-off, we hard-code the | |
// currently allowed teams with "good enough" details, since the actual team | |
// members don't matter here. | |
const TEAM_LIST = [ | |
'publishers', | |
'security', | |
'chartbeat', | |
'pinterest', | |
'twitter', | |
'automattic', | |
'rebelmouse', | |
'linkedin', | |
'nuzzel', | |
'adobe', | |
'comscore', | |
'google', | |
'jw-player', | |
'parsely', | |
'contributors', | |
'docs', | |
'video-on-amp', | |
'a4a', | |
'alp', | |
'runtime', | |
'cloudflare', | |
'validator', | |
'amp-viewer-master-mergers', | |
'skahp', | |
'microsoft', | |
'tsc', | |
'ac', | |
'wg-ui-and-a11y', | |
'working-groups', | |
'wg-amp4email', | |
'wg-approvers', | |
'wg-codeofconduct', | |
'wg-infra', | |
'wg-outreach', | |
'wg-runtime', | |
'wg-stories', | |
'wg-caching', | |
'wg-viewers', | |
'wg-access-subscriptions', | |
'wg-ads', | |
'wg-analytics', | |
'reviewers-amphtml', | |
'collaborators-amphtml', | |
'wg-performance', | |
'cherry-pick-approvers', | |
'bots-amphtml', | |
]; | |
const teamMap = {}; | |
TEAM_LIST.forEach(name => { | |
teamMap[`ampproject/${name}`] = new Team(0, 'ampproject', name); | |
}); | |
const repo = new LocalRepository(GITHUB_REPO_DIR); | |
const parser = new OwnersParser(repo, teamMap); | |
/** | |
* Serializes an owner into a JSON owner definition. | |
* | |
* @param {!Owner} owner owner to serialize. | |
* @return {OwnerDefinition} JSON owner definition. | |
*/ | |
function ownerToDefinition(owner) { | |
const ownerDef = {name: owner.name}; | |
if (owner.modifier === OWNER_MODIFIER.SILENT) { | |
ownerDef.requestReviews = false; | |
} | |
if (owner.modifier === OWNER_MODIFIER.NOTIFY) { | |
ownerDef.notify = true; | |
} | |
return ownerDef; | |
} | |
/** | |
* Serializes an owners rule into a JSON rule definition. | |
* | |
* @param {!OwnersRule} rule rule to serialize. | |
* @return {RuleDefinition} JSON rule definition. | |
*/ | |
function ruleToDefinition(rule) { | |
const ruleDef = {}; | |
if (rule instanceof SameDirPatternOwnersRule) { | |
ruleDef.pattern = rule.pattern; | |
} else if (rule instanceof PatternOwnersRule) { | |
ruleDef.pattern = `**/${rule.pattern}`; | |
} | |
ruleDef.owners = rule.owners.map(ownerToDefinition); | |
return ruleDef; | |
} | |
/** | |
* Converts an OWNERS.yaml file into an OWNERS JSON5 file. | |
* | |
* @param {!string} ownersPath path to OWNERS.yaml file. | |
*/ | |
function convertFile(ownersPath) { | |
const newOwnersPath = repo.getAbsolutePath(ownersPath).replace(/\.yaml$/, ''); | |
console.log(`Converting ${ownersPath} --> ${newOwnersPath}:`); | |
const {result, errors} = parser.parseOwnersFile(ownersPath) | |
const rules = result.map(ruleToDefinition); | |
let fileJson = JSON5.stringify({rules}, null, 2) | |
// Collapse owners declarations containing only a name onto one line. | |
.replace(/\{\s+name: "(.*?)"\s+\}/g, '{ name: "$1" }') | |
// Prefer single-quoted strings | |
.replace(/"/g, '\''); | |
const jsonContents = [FILE_COMMENT, fileJson]; | |
if (errors.length) { | |
errors.forEach(console.error); | |
const errorMessages = errors.map(error => `// ${error}`); | |
jsonContents.push(errorMessages.join('\n')); | |
} | |
fs.writeFileSync( | |
newOwnersPath, | |
`${jsonContents.join('\n\n')}\n`, | |
{encoding: 'utf8'}, | |
); | |
} | |
/** | |
* Converts all OWNERS.yaml files in the repo to OWNERS JSON5 files. | |
*/ | |
async function convertFiles() { | |
const yamlOwnersFiles = await repo.findOwnersFiles(); | |
for (let i = 0; i < yamlOwnersFiles.length; ++i) { | |
convertFile(yamlOwnersFiles[i]); | |
} | |
} | |
convertFiles().then(async () => { | |
const {result, errors} = await parser.parseOwnersTree(); | |
errors.forEach(console.error); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment