build: creates a script to get contributor stats from across the angular org (#35834)

This script gets all of the current users for the organization and retrieves
information about PR/Issue contributions/authorship since a provided date.
Returning this information as a CSV.

PR Close #35834
This commit is contained in:
Joey Perrott 2020-03-03 10:16:18 -08:00 committed by Matias Niemelä
parent 0bf6e58db2
commit 65a6848ed7
4 changed files with 384 additions and 1 deletions

View File

@ -952,6 +952,7 @@ groups:
'tools/browsers/**',
'tools/build/**',
'tools/circular_dependency_test/**',
'tools/contributing-stats/**',
'tools/gulp-tasks/**',
'tools/ng_rollup_bundle/**',
'tools/ngcontainer/**',

View File

@ -147,6 +147,7 @@
"@bazel/bazel": "2.1.0",
"@bazel/buildifier": "^0.29.0",
"@bazel/ibazel": "^0.11.1",
"@octokit/graphql": "^4.3.1",
"@types/minimist": "^1.2.0",
"@yarnpkg/lockfile": "^1.1.0",
"browserstacktunnel-wrapper": "2.0.1",
@ -175,9 +176,11 @@
"rewire": "2.5.2",
"sauce-connect": "https://saucelabs.com/downloads/sc-4.5.1-linux.tar.gz",
"semver": "^6.3.0",
"ts-node": "^8.6.2",
"tslint-eslint-rules": "5.4.0",
"tslint-no-toplevel-property-access": "0.0.2",
"tsutils": "2.27.2",
"typed-graphqlify": "^2.3.0",
"universal-analytics": "0.4.15",
"vlq": "0.2.2",
"vrsource-tslint-rules": "5.1.1"

View File

@ -0,0 +1,244 @@
/**
* @license
* Copyright Google Inc. All Rights Reserved.
*
* Use of this source code is governed by an MIT-style license that can be
* found in the LICENSE file at https://angular.io/license
*/
/**
* This script gets contribution stats for all members of the angular org,
* since a provided date.
* The script expects the following flag(s):
*
* required:
* --since [date] The data after which contributions are queried for.
* Uses githubs search format for dates, e.g. "2020-01-21".
* See
* https://help.github.com/en/github/searching-for-information-on-github/understanding-the-search-syntax#query-for-dates
*
* optional:
* --use-created [boolean] If the created timestamp should be used for
* time comparisons, defaults otherwise to the updated timestamp.
*/
import {graphql as unauthenticatedGraphql} from '@octokit/graphql';
import * as minimist from 'minimist';
import {alias, params, query as graphqlQuery, types} from 'typed-graphqlify';
// The organization to be considered for the queries.
const ORG = 'angular';
// The repositories to be considered for the queries.
const REPOS = ['angular', 'components', 'angular-cli'];
/**
* Handle flags for the script.
*/
const args = minimist(process.argv.slice(2), {
string: ['since'],
boolean: ['use-created'],
unknown: (option: string) => {
console.error(`Unknown option: ${option}`);
process.exit(1);
}
});
if (!args['since']) {
console.error(`Please provide --since [date]`);
process.exit(1);
}
/**
* Authenticated instance of Github GraphQl API service, relies on a
* personal access token being available in the TOKEN environment variable.
*/
const graphql = unauthenticatedGraphql.defaults({
headers: {
// TODO(josephperrott): Remove reference to TOKEN environment variable as part of larger
// effort to migrate to expecting tokens via GITHUB_ACCESS_TOKEN environment variables.
authorization: `token ${process.env.TOKEN || process.env.GITHUB_ACCESS_TOKEN}`,
}
});
/**
* Retrieves all current members of an organization.
*/
async function getAllOrgMembers() {
// The GraphQL query object to get a page of members of an organization.
const MEMBERS_QUERY = params(
{
$first: 'Int', // How many entries to get with each request
$after: 'String', // The cursor to start the page at
$owner: 'String!', // The organization to query for
},
{
organization: params({login: '$owner'}, {
membersWithRole: params(
{
first: '$first',
after: '$after',
},
{
nodes: [{login: types.string}],
pageInfo: {
hasNextPage: types.boolean,
endCursor: types.string,
},
}),
})
});
const query = graphqlQuery('members', MEMBERS_QUERY);
/**
* Gets the query and queryParams for a specific page of entries.
*/
const queryBuilder = (count: number, cursor?: string) => {
return {
query,
params: {
after: cursor || null,
first: count,
owner: ORG,
},
};
};
// The current cursor
let cursor = undefined;
// If an additional page of members is expected
let hasNextPage = true;
// Array of Github usernames of the organization
const members: string[] = [];
while (hasNextPage) {
const {query, params} = queryBuilder(100, cursor);
const results = await graphql(query, params) as typeof MEMBERS_QUERY;
results.organization.membersWithRole.nodes.forEach(
(node: {login: string}) => members.push(node.login));
hasNextPage = results.organization.membersWithRole.pageInfo.hasNextPage;
cursor = results.organization.membersWithRole.pageInfo.endCursor;
}
return members;
}
/**
* Build metadata for making requests for a specific user and date.
*
* Builds GraphQL query string, Query Params and Labels for making queries to GraphQl.
*/
function buildQueryAndParams(username: string, date: string) {
// Whether the updated or created timestamp should be used.
const updatedOrCreated = args['use-created'] ? 'created' : 'updated';
let dataQueries: {[key: string]: {query: string, label: string}} = {};
// Add queries and params for all values queried for each repo.
for (let repo of REPOS) {
dataQueries = {
...dataQueries,
[`${repo.replace(/[\/\-]/g, '_')}_issue_author`]: {
query: `repo:${ORG}/${repo} is:issue author:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG}/${repo} Issue Authored`,
},
[`${repo.replace(/[\/\-]/g, '_')}_issues_involved`]: {
query:
`repo:${ORG}/${repo} is:issue -author:${username} involves:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG}/${repo} Issue Involved`,
},
[`${repo.replace(/[\/\-]/g, '_')}_pr_author`]: {
query: `repo:${ORG}/${repo} is:pr author:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG}/${repo} PR Author`,
},
[`${repo.replace(/[\/\-]/g, '_')}_pr_involved`]: {
query: `repo:${ORG}/${repo} is:pr involves:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG}/${repo} PR Involved`,
},
[`${repo.replace(/[\/\-]/g, '_')}_pr_reviewed`]: {
query:
`repo:${ORG}/${repo} is:pr -author:${username} reviewed-by:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG}/${repo} PR Reviewed`,
},
[`${repo.replace(/[\/\-]/g, '_')}_pr_commented`]: {
query:
`repo:${ORG}/${repo} is:pr -author:${username} commenter:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG}/${repo} PR Commented`,
},
};
}
// Add queries and params for all values queried for the org.
dataQueries = {
...dataQueries,
[`${ORG}_org_issue_author`]: {
query: `org:${ORG} is:issue author:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG} org Issue Authored`,
},
[`${ORG}_org_issues_involved`]: {
query:
`org:${ORG} is:issue -author:${username} involves:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG} org Issue Involved`,
},
[`${ORG}_org_pr_author`]: {
query: `org:${ORG} is:pr author:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG} org PR Author`,
},
[`${ORG}_org_pr_involved`]: {
query: `org:${ORG} is:pr involves:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG} org PR Involved`,
},
[`${ORG}_org_pr_reviewed`]: {
query:
`org:${ORG} is:pr -author:${username} reviewed-by:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG} org PR Reviewed`,
},
[`${ORG}_org_pr_commented`]: {
query:
`org:${ORG} is:pr -author:${username} commenter:${username} ${updatedOrCreated}:>${date}`,
label: `${ORG} org PR Commented`,
},
};
/**
* Gets the labels for each requested value to be used as headers.
*/
function getLabels(pairs: typeof dataQueries) {
return Object.values(pairs).map(val => val.label);
}
/**
* Gets the graphql query object for the GraphQL query.
*/
function getQuery(pairs: typeof dataQueries) {
const output: {[key: string]: {}} = {};
Object.entries(pairs).map(([key, val]) => {
output[alias(key, 'search')] = params(
{
query: `"${val.query}"`,
type: 'ISSUE',
},
{
issueCount: types.number,
});
});
return output;
}
return {
query: graphqlQuery(getQuery(dataQueries)),
labels: getLabels(dataQueries),
};
}
/**
* Runs the script to create a CSV string with the requested data for each member
* of the organization.
*/
async function run(date: string) {
console.info(['Username'].concat(buildQueryAndParams('', date).labels).join(','));
for (let username of await getAllOrgMembers()) {
const results = await graphql(buildQueryAndParams(username, date).query);
const values = Object.values(results).map(result => `${result.issueCount}`);
console.info([username].concat(values).join(','));
}
}
run(args['since']);

137
yarn.lock
View File

@ -1274,6 +1274,54 @@
rxjs "6.5.3"
webpack-sources "1.4.3"
"@octokit/endpoint@^5.5.0":
version "5.5.3"
resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-5.5.3.tgz#0397d1baaca687a4c8454ba424a627699d97c978"
integrity sha512-EzKwkwcxeegYYah5ukEeAI/gYRLv2Y9U5PpIsseGSFDk+G3RbipQGBs8GuYS1TLCtQaqoO66+aQGtITPalxsNQ==
dependencies:
"@octokit/types" "^2.0.0"
is-plain-object "^3.0.0"
universal-user-agent "^5.0.0"
"@octokit/graphql@^4.3.1":
version "4.3.1"
resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-4.3.1.tgz#9ee840e04ed2906c7d6763807632de84cdecf418"
integrity sha512-hCdTjfvrK+ilU2keAdqNBWOk+gm1kai1ZcdjRfB30oA3/T6n53UVJb7w0L5cR3/rhU91xT3HSqCd+qbvH06yxA==
dependencies:
"@octokit/request" "^5.3.0"
"@octokit/types" "^2.0.0"
universal-user-agent "^4.0.0"
"@octokit/request-error@^1.0.1":
version "1.2.1"
resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-1.2.1.tgz#ede0714c773f32347576c25649dc013ae6b31801"
integrity sha512-+6yDyk1EES6WK+l3viRDElw96MvwfJxCt45GvmjDUKWjYIb3PJZQkq3i46TwGwoPD4h8NmTrENmtyA1FwbmhRA==
dependencies:
"@octokit/types" "^2.0.0"
deprecation "^2.0.0"
once "^1.4.0"
"@octokit/request@^5.3.0":
version "5.3.2"
resolved "https://registry.yarnpkg.com/@octokit/request/-/request-5.3.2.tgz#1ca8b90a407772a1ee1ab758e7e0aced213b9883"
integrity sha512-7NPJpg19wVQy1cs2xqXjjRq/RmtSomja/VSWnptfYwuBxLdbYh2UjhGi0Wx7B1v5Iw5GKhfFDQL7jM7SSp7K2g==
dependencies:
"@octokit/endpoint" "^5.5.0"
"@octokit/request-error" "^1.0.1"
"@octokit/types" "^2.0.0"
deprecation "^2.0.0"
is-plain-object "^3.0.0"
node-fetch "^2.3.0"
once "^1.4.0"
universal-user-agent "^5.0.0"
"@octokit/types@^2.0.0":
version "2.3.1"
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-2.3.1.tgz#40cd61c125a6161cfb3bfabc75805ac7a54213b4"
integrity sha512-rvJP1Y9A/+Cky2C3var1vsw3Lf5Rjn/0sojNl2AjCX+WbpIHYccaJ46abrZoIxMYnOToul6S9tPytUVkFI7CXQ==
dependencies:
"@types/node" ">= 8"
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
@ -1549,6 +1597,11 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.8.tgz#92509422653f10e9c0ac18d87e0610b39f9821c7"
integrity sha512-8KmlRxwbKZfjUHFIt3q8TF5S2B+/E5BaAoo/3mgc5h6FJzqxXkCK/VMetO+IRDtwtU6HUvovHMBn+XRj7SV9Qg==
"@types/node@>= 8":
version "13.7.7"
resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99"
integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==
"@types/node@^10.1.0":
version "10.14.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.14.4.tgz#1c586b991457cbb58fef51bc4e0cfcfa347714b5"
@ -2347,6 +2400,11 @@ are-we-there-yet@~1.1.2:
delegates "^1.0.0"
readable-stream "^2.0.6"
arg@^4.1.0:
version "4.1.3"
resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089"
integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==
argparse@^1.0.7, argparse@~1.0.9:
version "1.0.10"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911"
@ -4853,6 +4911,11 @@ deprecated@^0.0.1:
resolved "https://registry.yarnpkg.com/deprecated/-/deprecated-0.0.1.tgz#f9c9af5464afa1e7a971458a8bdef2aa94d5bb19"
integrity sha1-+cmvVGSvoeepcUWKi97yqpTVuxk=
deprecation@^2.0.0:
version "2.3.1"
resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919"
integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==
des.js@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843"
@ -8119,6 +8182,13 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4:
dependencies:
isobject "^3.0.1"
is-plain-object@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-3.0.0.tgz#47bfc5da1b5d50d64110806c199359482e75a928"
integrity sha512-tZIpofR+P05k8Aocp7UI/2UTa9lTJSebCXpFFoR9aibpokDj/uXBsJ8luUu0tTVYKkMU6URDUuOfJZ7koewXvg==
dependencies:
isobject "^4.0.0"
is-posix-bracket@^0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4"
@ -8331,6 +8401,11 @@ isobject@^3.0.0, isobject@^3.0.1:
resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df"
integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8=
isobject@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0"
integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA==
isstream@0.1.x, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
@ -9476,6 +9551,11 @@ lru-queue@0.1:
dependencies:
es5-ext "~0.10.2"
macos-release@^2.2.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
integrity sha512-OHhSbtcviqMPt7yfw5ef5aghS2jzFVKEFyCJndQt2YpSQ9qRVSEv2axSJI1paVThEu+FFGs584h/1YhxjVqajA==
madge@^3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/madge/-/madge-3.6.0.tgz#f69e7c3e15a18a195e6bcd7942cc36efabcd9b9a"
@ -9539,6 +9619,11 @@ make-dir@^3.0.0:
dependencies:
semver "^6.0.0"
make-error@^1.1.1:
version "1.3.6"
resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2"
integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==
make-fetch-happen@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-5.0.0.tgz#a8e3fe41d3415dd656fe7b8e8172e1fb4458b38d"
@ -10904,6 +10989,14 @@ os-locale@^3.0.0, os-locale@^3.1.0:
lcid "^2.0.0"
mem "^4.0.0"
os-name@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/os-name/-/os-name-3.1.0.tgz#dec19d966296e1cd62d701a5a66ee1ddeae70801"
integrity sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==
dependencies:
macos-release "^2.2.0"
windows-release "^3.1.0"
os-shim@^0.1.2:
version "0.1.3"
resolved "https://registry.yarnpkg.com/os-shim/-/os-shim-0.1.3.tgz#6b62c3791cf7909ea35ed46e17658bb417cb3917"
@ -13485,7 +13578,7 @@ source-map-support@0.4.3:
dependencies:
source-map "^0.5.3"
source-map-support@0.5.16, source-map-support@^0.5.5, source-map-support@~0.5.12:
source-map-support@0.5.16, source-map-support@^0.5.5, source-map-support@^0.5.6, source-map-support@~0.5.12:
version "0.5.16"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.16.tgz#0ae069e7fe3ba7538c64c98515e35339eac5a042"
integrity sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==
@ -14603,6 +14696,17 @@ try-require@^1.0.0:
resolved "https://registry.yarnpkg.com/try-require/-/try-require-1.2.1.tgz#34489a2cac0c09c1cc10ed91ba011594d4333be2"
integrity sha1-NEiaLKwMCcHMEO2RugEVlNQzO+I=
ts-node@^8.6.2:
version "8.6.2"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-8.6.2.tgz#7419a01391a818fbafa6f826a33c1a13e9464e35"
integrity sha512-4mZEbofxGqLL2RImpe3zMJukvEvcO1XP8bj8ozBPySdCUXEcU5cIRwR0aM3R+VoZq7iXc8N86NC0FspGRqP4gg==
dependencies:
arg "^4.1.0"
diff "^4.0.1"
make-error "^1.1.1"
source-map-support "^0.5.6"
yn "3.1.1"
tsickle@0.38.0:
version "0.38.0"
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.38.0.tgz#89f5952c9bb3ba0b36dc384975e23cf90e584822"
@ -14754,6 +14858,11 @@ type@^2.0.0:
resolved "https://registry.yarnpkg.com/type/-/type-2.0.0.tgz#5f16ff6ef2eb44f260494dae271033b29c09a9c3"
integrity sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==
typed-graphqlify@^2.3.0:
version "2.3.0"
resolved "https://registry.yarnpkg.com/typed-graphqlify/-/typed-graphqlify-2.3.0.tgz#c85f09b65b56e6da2c993899a34e551e2616bf91"
integrity sha512-iRjAneX/0gHBOrJnZGF5Nwl6OjHDiYBYxQzqenRJExVod0A0QHto9npX4d68i+2OuSHAzatNgSVtJoRgnBHeYQ==
typedarray@^0.0.6:
version "0.0.6"
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
@ -14912,6 +15021,20 @@ universal-analytics@^0.4.16, universal-analytics@^0.4.20:
request "^2.88.0"
uuid "^3.0.0"
universal-user-agent@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-4.0.1.tgz#fd8d6cb773a679a709e967ef8288a31fcc03e557"
integrity sha512-LnST3ebHwVL2aNe4mejI9IQh2HfZ1RLo8Io2HugSif8ekzD1TlWpHpColOB/eh8JHMLkGH3Akqf040I+4ylNxg==
dependencies:
os-name "^3.1.0"
universal-user-agent@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-5.0.0.tgz#a3182aa758069bf0e79952570ca757de3579c1d9"
integrity sha512-B5TPtzZleXyPrUMKCpEHFmVhMN6EhmJYjG5PQna9s7mXeSqGTLap4OpqLl5FCEFUI3UBmllkETwKf/db66Y54Q==
dependencies:
os-name "^3.1.0"
universalify@^0.1.0:
version "0.1.2"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66"
@ -15486,6 +15609,13 @@ widest-line@^2.0.0:
dependencies:
string-width "^2.1.1"
windows-release@^3.1.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.2.0.tgz#8122dad5afc303d833422380680a79cdfa91785f"
integrity sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==
dependencies:
execa "^1.0.0"
winreg@0.0.12:
version "0.0.12"
resolved "https://registry.yarnpkg.com/winreg/-/winreg-0.0.12.tgz#07105554ba1a9d08979251d129475bffae3006b7"
@ -15770,6 +15900,11 @@ yeast@0.1.2:
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
z-schema@~3.18.3:
version "3.18.4"
resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-3.18.4.tgz#ea8132b279533ee60be2485a02f7e3e42541a9a2"