From d299dd9322ebf58cc3e9ddd31a491023b2d492b4 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 2 Jan 2021 09:47:16 -0800 Subject: [PATCH 001/172] Update CONTRIBUTING.md --- CONTRIBUTING.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 22191610..02177a03 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -22,6 +22,12 @@ You must install these tools: 1. [`git`](https://help.github.com/articles/set-up-git/): For source control. 1. [`python`](https://www.python.org/downloads/): For running code. + +1. [`python-gitlab`] and [`PyGithub`] pip packages. + +```shell +pip3 install python-gitlab PyGithub +``` ## Iterating From d9a751e23cd8da7494240ae4e34dab2a041a4bc2 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 2 Jan 2021 09:47:58 -0800 Subject: [PATCH 002/172] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 02177a03..f848f964 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ You must install these tools: 1. [`python`](https://www.python.org/downloads/): For running code. -1. [`python-gitlab`] and [`PyGithub`] pip packages. +1. `python-gitlab` and `PyGithub` pip packages. ```shell pip3 install python-gitlab PyGithub From a5374b4b5dcb65b9d5bd9f6d8c5a0e456cf3106b Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 2 Jan 2021 09:48:59 -0800 Subject: [PATCH 003/172] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f848f964..7b8256af 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -23,7 +23,7 @@ You must install these tools: 1. [`python`](https://www.python.org/downloads/): For running code. -1. `python-gitlab` and `PyGithub` pip packages. +1. [`python-gitlab`](https://pypi.org/project/python-gitlab/) and [`PyGithub`](https://pypi.org/project/PyGithub/) pip packages. ```shell pip3 install python-gitlab PyGithub From 777453e6940eaeda933df723ce6d8dd43b807751 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 2 Jan 2021 09:54:29 -0800 Subject: [PATCH 004/172] Fixes #59, add pip deps needed for generate script run. --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 2891a4b9..07d991db 100644 --- a/README.md +++ b/README.md @@ -143,6 +143,7 @@ This data is generated using this For example, to generate a list of top 200 C language projects, run: ```shell +$ pip3 install python-gitlab PyGithub $ python3 -u -m criticality_score.generate \ --language c --count 200 --sample-size 5000 ``` From 6cd5db602fbb3fa434bc1db37aebbae7b54f3e56 Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 2 Jan 2021 22:33:21 +0300 Subject: [PATCH 005/172] Make language parameter optional --- criticality_score/generate.py | 96 +++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 44 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 879c878b..0a1a4d4d 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -36,48 +36,47 @@ } IGNORED_KEYWORDS = ['book', 'course', 'docs', 'interview', 'tutorial'] - -def get_repo_urls(languages, sample_size): +def get_repo_urls(urls, sample_size, github_lang = ''): """Return repository urls given a language list and sample size.""" - repo_urls = [] - for lang in languages: - lang = lang.lower() - for github_lang in LANGUAGE_SEARCH_MAP.get(lang, lang): - samples_processed = 1 - last_stars_processed = None - while samples_processed <= sample_size: - query = f'language:{github_lang} archived:false' - if last_stars_processed: - # +100 to avoid any races with star updates. - query += f' stars:<{last_stars_processed+100}' - print(f'Running query: {query}') - token_obj = run.get_github_auth_token() - new_result = False - repo = None - for repo in token_obj.search_repositories(query=query, - sort='stars', - order='desc'): - # Forced sleep to avoid hitting rate limit. - time.sleep(0.1) - repo_url = repo.html_url - if repo_url in repo_urls: - # Github search can return duplicates, so skip if analyzed. - continue - if any(k in repo_url.lower() for k in IGNORED_KEYWORDS): - # Ignore uninteresting repositories. - continue - repo_urls.append(repo_url) - new_result = True - print(f'Found {github_lang} repository' - f'({samples_processed}): {repo_url}') - samples_processed += 1 - if samples_processed > sample_size: - break - if not new_result: - break - last_stars_processed = repo.stargazers_count - - return repo_urls + samples_processed = 1 + last_stars_processed = None + while samples_processed <= sample_size: + + query = 'archived:false' + if github_lang: + query += f' language:{github_lang}' + + if last_stars_processed: + # +100 to avoid any races with star updates. + query += f' stars:<{last_stars_processed+100}' + print(f'Running query: {query}') + token_obj = run.get_github_auth_token() + new_result = False + repo = None + for repo in token_obj.search_repositories(query=query, + sort='stars', + order='desc'): + # Forced sleep to avoid hitting rate limit. + time.sleep(0.1) + repo_url = repo.html_url + if repo_url in urls: + # Github search can return duplicates, so skip if analyzed. + continue + if any(k in repo_url.lower() for k in IGNORED_KEYWORDS): + # Ignore uninteresting repositories. + continue + urls.append(repo_url) + new_result = True + print(f'Found repository' + f'({samples_processed}): {repo_url}') + samples_processed += 1 + if samples_processed > sample_size: + break + if not new_result: + break + last_stars_processed = repo.stargazers_count + + return urls def main(): @@ -87,7 +86,7 @@ def main(): parser.add_argument("--language", nargs='+', default=[], - required=True, + required=False, choices=LANGUAGE_SEARCH_MAP.keys(), help="List of languages to use.") parser.add_argument("--output-dir", @@ -111,7 +110,16 @@ def main(): repo_urls = set() for rnd in range(1, 4): print(f'Finding repos (round {rnd}):') - repo_urls.update(get_repo_urls(args.language, args.sample_size)) + urls = [] + if (args.language): + for lang in args.language: + lang = lang.lower() + for github_lang in LANGUAGE_SEARCH_MAP.get(lang, lang): + urls = get_repo_urls(urls, args.sample_size, github_lang) + else: + urls = get_repo_urls(urls, args.sample_size) + + repo_urls.update(urls) csv_writer = csv.writer(sys.stdout) header = None @@ -134,7 +142,7 @@ def main(): csv_writer.writerow(output.values()) stats.append(output) - languages = '_'.join(args.language) + languages = '_'.join(args.language) if args.language else 'all' languages = languages.replace('+', 'plus').replace('c#', 'csharp') output_filename = os.path.join(args.output_dir, f'{languages}_top_{args.count}.csv') From db20ba3f2097ecf7fc0be7b54635403648fbadd7 Mon Sep 17 00:00:00 2001 From: coni2k Date: Sun, 3 Jan 2021 10:38:14 +0300 Subject: [PATCH 006/172] - Create 'get_github_repo_urls' function - Update 'github_lang' default value --- criticality_score/generate.py | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 0a1a4d4d..3aec6576 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -36,7 +36,19 @@ } IGNORED_KEYWORDS = ['book', 'course', 'docs', 'interview', 'tutorial'] -def get_repo_urls(urls, sample_size, github_lang = ''): +def get_github_repo_urls(sample_size, languages): + urls = [] + if (languages): + for lang in languages: + lang = lang.lower() + for github_lang in LANGUAGE_SEARCH_MAP.get(lang, lang): + urls = get_github_repo_urls_for_language(urls, sample_size, github_lang) + else: + urls = get_github_repo_urls_for_language(urls, sample_size) + + return urls + +def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): """Return repository urls given a language list and sample size.""" samples_processed = 1 last_stars_processed = None @@ -110,16 +122,7 @@ def main(): repo_urls = set() for rnd in range(1, 4): print(f'Finding repos (round {rnd}):') - urls = [] - if (args.language): - for lang in args.language: - lang = lang.lower() - for github_lang in LANGUAGE_SEARCH_MAP.get(lang, lang): - urls = get_repo_urls(urls, args.sample_size, github_lang) - else: - urls = get_repo_urls(urls, args.sample_size) - - repo_urls.update(urls) + repo_urls.update(get_github_repo_urls(args.sample_size, args.language)) csv_writer = csv.writer(sys.stdout) header = None From 4370726b49c01d7f21665b71dffb46615ea0f5b0 Mon Sep 17 00:00:00 2001 From: coni2k Date: Sun, 3 Jan 2021 14:07:13 +0300 Subject: [PATCH 007/172] - Update Readme to include output-dir parameter - Create a output folder --- README.md | 2 +- output/.gitignore | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 output/.gitignore diff --git a/README.md b/README.md index 07d991db..c1ce3a4d 100644 --- a/README.md +++ b/README.md @@ -145,7 +145,7 @@ For example, to generate a list of top 200 C language projects, run: ```shell $ pip3 install python-gitlab PyGithub $ python3 -u -m criticality_score.generate \ - --language c --count 200 --sample-size 5000 + --language c --count 200 --sample-size 5000 --output-dir output ``` diff --git a/output/.gitignore b/output/.gitignore new file mode 100644 index 00000000..5e7d2734 --- /dev/null +++ b/output/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore From 20a95315823d759b6ec181ae3bbd4f8a1705d84a Mon Sep 17 00:00:00 2001 From: coni2k Date: Sun, 3 Jan 2021 14:22:14 +0300 Subject: [PATCH 008/172] Create .gitignore file --- .gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..ba0430d2 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +__pycache__/ \ No newline at end of file From 3143a8b5d73e838e30ec6c65aecce7f5ff7dca76 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Tue, 5 Jan 2021 08:37:43 -0800 Subject: [PATCH 009/172] Remove book as causes legit repos like facebookresearch to be removed. --- criticality_score/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 3aec6576..396a17c8 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -34,7 +34,7 @@ 'rust': ['Rust'], 'shell': ['Shell'], } -IGNORED_KEYWORDS = ['book', 'course', 'docs', 'interview', 'tutorial'] +IGNORED_KEYWORDS = ['course', 'docs', 'interview', 'tutorial'] def get_github_repo_urls(sample_size, languages): urls = [] From 8ca5228be499c739826c1802b8f870fac670ad5d Mon Sep 17 00:00:00 2001 From: Yikun Jiang Date: Fri, 8 Jan 2021 17:32:28 +0800 Subject: [PATCH 010/172] Bump python_requires to 3.6 The criticality_score is using some high version feature, such as `print(f'')` Formatted string literals[1], which is added in pyhton 3.6. That means it would be break down in the version before python 3.6. This patch we bump the python_requires to 3.6 to make sure the script works well. [1] https://docs.python.org/3.6/reference/lexical_analysis.html#formatted-string-literals --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index c821be8d..183b1b96 100644 --- a/setup.py +++ b/setup.py @@ -39,6 +39,6 @@ entry_points={ 'console_scripts': ['criticality_score=criticality_score.run:main'], }, - python_requires='>=3', + python_requires='>=3.6', zip_safe=False, ) From 5c227ddc984723daf5340490347c521914645e8d Mon Sep 17 00:00:00 2001 From: coni2k Date: Fri, 8 Jan 2021 23:06:01 +0300 Subject: [PATCH 011/172] Add logging --- criticality_score/generate.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 396a17c8..2dd255b6 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -18,6 +18,7 @@ import os import sys import time +import logging from . import run @@ -117,6 +118,17 @@ def main(): args = parser.parse_args() + # logging + log_filename = os.path.join(args.output_dir, 'generate.log') + logging.basicConfig(filename=log_filename, filemode="w", level=logging.WARNING) + + # console handler + console = logging.StreamHandler() + console.setLevel(logging.ERROR) + logging.getLogger("").addHandler(console) + + logger = logging.getLogger(__name__) + # GitHub search can return incomplete results in a query, so try it multiple # times to avoid missing urls. repo_urls = set() @@ -135,8 +147,9 @@ def main(): output = run.get_repository_stats(repo) break except Exception as exp: - print( - f'Exception occurred when reading repo: {repo_url}\n{exp}') + msg = f'Exception occurred when reading repo: {repo_url}\n{exp}' + print(msg) + logger.exception(msg) if not output: continue if not header: From 0c295b56729b41f85801899206275d5bb9f5df91 Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 9 Jan 2021 13:12:48 +0300 Subject: [PATCH 012/172] - Move logger to global - Replace print with logger.info - Set loglevel to info --- criticality_score/generate.py | 36 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 2dd255b6..04321e7b 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -15,13 +15,15 @@ import argparse import csv +import logging import os import sys import time -import logging from . import run +logger = logging.getLogger() + LANGUAGE_SEARCH_MAP = { 'c': ['C'], 'c#': ['C#'], @@ -62,7 +64,7 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): if last_stars_processed: # +100 to avoid any races with star updates. query += f' stars:<{last_stars_processed+100}' - print(f'Running query: {query}') + logger.info(f'Running query: {query}') token_obj = run.get_github_auth_token() new_result = False repo = None @@ -80,7 +82,7 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): continue urls.append(repo_url) new_result = True - print(f'Found repository' + logger.info(f'Found repository' f'({samples_processed}): {repo_url}') samples_processed += 1 if samples_processed > sample_size: @@ -93,6 +95,15 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): def main(): + # logging + log_filename = os.path.join('output', 'generate.log') + logging.basicConfig(filename=log_filename, filemode='w', level=logging.INFO) + + # console handler + console = logging.StreamHandler() + console.setLevel(logging.INFO) + logging.getLogger('').addHandler(console) + parser = argparse.ArgumentParser( description= 'Generate a sorted criticality score list for particular language(s).') @@ -118,22 +129,11 @@ def main(): args = parser.parse_args() - # logging - log_filename = os.path.join(args.output_dir, 'generate.log') - logging.basicConfig(filename=log_filename, filemode="w", level=logging.WARNING) - - # console handler - console = logging.StreamHandler() - console.setLevel(logging.ERROR) - logging.getLogger("").addHandler(console) - - logger = logging.getLogger(__name__) - # GitHub search can return incomplete results in a query, so try it multiple # times to avoid missing urls. repo_urls = set() for rnd in range(1, 4): - print(f'Finding repos (round {rnd}):') + logger.info(f'Finding repos (round {rnd}):') repo_urls.update(get_github_repo_urls(args.sample_size, args.language)) csv_writer = csv.writer(sys.stdout) @@ -147,9 +147,7 @@ def main(): output = run.get_repository_stats(repo) break except Exception as exp: - msg = f'Exception occurred when reading repo: {repo_url}\n{exp}' - print(msg) - logger.exception(msg) + logger.exception(f'Exception occurred when reading repo: {repo_url}\n{exp}') if not output: continue if not header: @@ -169,7 +167,7 @@ def main(): key=lambda i: i['criticality_score'], reverse=True)[:args.count]: csv_writer.writerow(i.values()) - print(f'Wrote results: {output_filename}') + logger.info(f'Wrote results: {output_filename}') if __name__ == "__main__": From 7a2b94391d4d6f734a44652bc3ab96765bc961d0 Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 9 Jan 2021 21:03:56 +0300 Subject: [PATCH 013/172] Review updates https://github.com/ossf/criticality_score/pull/66#pullrequestreview-564798129 --- criticality_score/generate.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 04321e7b..45829f74 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -93,17 +93,15 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): return urls - -def main(): - # logging - log_filename = os.path.join('output', 'generate.log') +def initialize_logging_handlers(output_dir): + log_filename = os.path.join(output_dir, 'output.log') logging.basicConfig(filename=log_filename, filemode='w', level=logging.INFO) - # console handler console = logging.StreamHandler() console.setLevel(logging.INFO) - logging.getLogger('').addHandler(console) + logging.getLogger('').addHandler(console) +def main(): parser = argparse.ArgumentParser( description= 'Generate a sorted criticality score list for particular language(s).') @@ -129,6 +127,8 @@ def main(): args = parser.parse_args() + initialize_logging_handlers(args.output_dir) + # GitHub search can return incomplete results in a query, so try it multiple # times to avoid missing urls. repo_urls = set() From 6ce58ebe21868d13fc56c420595cbbb773ef20e3 Mon Sep 17 00:00:00 2001 From: coni2k Date: Fri, 8 Jan 2021 22:08:20 +0300 Subject: [PATCH 014/172] Format the output of generate script --- criticality_score/generate.py | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 45829f74..a3ad7b55 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -136,9 +136,8 @@ def main(): logger.info(f'Finding repos (round {rnd}):') repo_urls.update(get_github_repo_urls(args.sample_size, args.language)) - csv_writer = csv.writer(sys.stdout) - header = None stats = [] + index = 1 for repo_url in repo_urls: output = None for _ in range(3): @@ -150,11 +149,9 @@ def main(): logger.exception(f'Exception occurred when reading repo: {repo_url}\n{exp}') if not output: continue - if not header: - header = output.keys() - csv_writer.writerow(header) - csv_writer.writerow(output.values()) + logger.info(f"{index} - {output['name']} - {output['url']} - {output['criticality_score']}") stats.append(output) + index += 1 languages = '_'.join(args.language) if args.language else 'all' languages = languages.replace('+', 'plus').replace('c#', 'csharp') @@ -162,6 +159,7 @@ def main(): f'{languages}_top_{args.count}.csv') with open(output_filename, 'w') as file_handle: csv_writer = csv.writer(file_handle) + header = output.keys() csv_writer.writerow(header) for i in sorted(stats, key=lambda i: i['criticality_score'], From cae562b0e0dd0bf9a043026a77b11f6fd1e1138a Mon Sep 17 00:00:00 2001 From: Yikun Jiang Date: Tue, 12 Jan 2021 15:44:34 +0800 Subject: [PATCH 015/172] Make sure criticality_score between 0 and 1 Due to the negative weight, the numerator of score may be greater than the denominator, that means the score would be greater than 1. And the numerator may be also less than 0, that means final score would be less than 0. So in this patch, we set the finall criticality_score between 0 (least-critical) and 1 (most-critical). --- criticality_score/run.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/criticality_score/run.py b/criticality_score/run.py index 333dbdb1..6296bfcc 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -456,6 +456,9 @@ def _worker(repo, param, return_dict): DEPENDENTS_COUNT_WEIGHT)) + additional_params_score) / total_weight, 5) + # Make sure score between 0 (least-critical) and 1 (most-critical). + criticality_score = max(min(criticality_score, 1), 0) + result_dict['criticality_score'] = criticality_score return result_dict From 0e88035f8cfb84b6ae19d00a3bff63ea13bbe52c Mon Sep 17 00:00:00 2001 From: coni2k Date: Tue, 12 Jan 2021 10:07:10 +0300 Subject: [PATCH 016/172] Refactor get_github_auth_token --- criticality_score/generate.py | 2 +- criticality_score/run.py | 83 +++++++++++++++++++++-------------- 2 files changed, 50 insertions(+), 35 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index a3ad7b55..1523f90f 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -65,7 +65,7 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): # +100 to avoid any races with star updates. query += f' stars:<{last_stars_processed+100}' logger.info(f'Running query: {query}') - token_obj = run.get_github_auth_token() + token_obj = run.get_github_auth_token()['token_obj'] new_result = False repo = None for repo in token_obj.search_repositories(query=query, diff --git a/criticality_score/run.py b/criticality_score/run.py index 333dbdb1..005e622e 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -31,7 +31,7 @@ from .constants import * # pylint: disable=wildcard-import _CACHED_GITHUB_TOKEN = None -_CACHED_GITHUB_TOKEN_OBJ = None +_CACHED_GITHUB_TOKENS = [] PARAMS = [ 'created_since', 'updated_since', 'contributor_count', 'org_count', @@ -143,7 +143,8 @@ def _parse_links(response): links[match.group(2)] = match.group(1) return links - headers = {'Authorization': f'token {_CACHED_GITHUB_TOKEN}'} + token = _CACHED_GITHUB_TOKEN['token'] + headers = {'Authorization': f'token {token}'} for i in range(FAIL_RETRIES): result = requests.get(f'{self._repo.url}/commits', headers=headers) links = _parse_links(result) @@ -460,41 +461,54 @@ def _worker(repo, param, return_dict): return result_dict -def get_github_token_info(token_obj): - """Return expiry information given a github token.""" - rate_limit = token_obj.get_rate_limit() - near_expiry = rate_limit.core.remaining < 50 - wait_time = (rate_limit.core.reset - datetime.datetime.utcnow()).seconds - return near_expiry, wait_time - +def get_github_auth_token_info(auth_token): + """If near expiry, sets reset information given a github token.""" + rate_limit = auth_token['token_obj'].get_rate_limit() + if rate_limit.core.remaining < 50: + auth_token['reset'] = rate_limit.core.reset + def get_github_auth_token(): """Return an un-expired github token if possible from a list of tokens.""" global _CACHED_GITHUB_TOKEN - global _CACHED_GITHUB_TOKEN_OBJ - if _CACHED_GITHUB_TOKEN_OBJ: - near_expiry, _ = get_github_token_info(_CACHED_GITHUB_TOKEN_OBJ) - if not near_expiry: - return _CACHED_GITHUB_TOKEN_OBJ - - github_auth_token = os.getenv('GITHUB_AUTH_TOKEN') - assert github_auth_token, 'GITHUB_AUTH_TOKEN needs to be set.' - tokens = github_auth_token.split(',') - - wait_time = None - token_obj = None - for token in tokens: - token_obj = github.Github(token) - near_expiry, wait_time = get_github_token_info(token_obj) - if not near_expiry: - _CACHED_GITHUB_TOKEN = token - _CACHED_GITHUB_TOKEN_OBJ = token_obj - return token_obj - - print(f'Rate limit exceeded, sleeping till reset: {wait_time} seconds.', - file=sys.stderr) - time.sleep(wait_time) - return token_obj + + # Initialize _CACHED_GITHUB_TOKENS that stores token, token_obj and reset data as a list + if not _CACHED_GITHUB_TOKENS: + github_auth_token = os.getenv('GITHUB_AUTH_TOKEN') + assert github_auth_token, 'GITHUB_AUTH_TOKEN needs to be set.' # TODO Validate earlier? + for token in github_auth_token.split(','): + token_obj = github.Github(token) + _CACHED_GITHUB_TOKENS.append({ 'token': token, 'token_obj': token_obj, 'reset': None }) + + while True: + # If there's an active token that's not near expiry, use that one + if _CACHED_GITHUB_TOKEN: + get_github_auth_token_info(_CACHED_GITHUB_TOKEN) + if not _CACHED_GITHUB_TOKEN['reset']: + return _CACHED_GITHUB_TOKEN + + # Else, search for the next token + for item in _CACHED_GITHUB_TOKENS: + if item['reset']: # Ignore already expired tokens + continue + + get_github_auth_token_info(item) + if not item['reset']: + _CACHED_GITHUB_TOKEN = item + return item + + # If all tokens are expired, find the minimum wait_time, clear the variables & sleep + wait_time = None + for item in _CACHED_GITHUB_TOKENS: + diff = (item['reset'] - datetime.datetime.utcnow()).seconds + 5 + if not wait_time or diff < wait_time: + wait_time = diff + item['reset'] = None + _CACHED_GITHUB_TOKEN = None + + print(f'Rate limit exceeded. Sleeping till reset: {round((wait_time / 60), 1)} minutes.', + file=sys.stderr) + time.sleep(wait_time) def get_gitlab_auth_token(host): @@ -518,7 +532,8 @@ def get_repository(url): parsed_url = urllib.parse.urlparse(url) repo_url = parsed_url.path.strip('/') if parsed_url.netloc.endswith('github.com'): - repo = GitHubRepository(get_github_auth_token().get_repo(repo_url)) + token_obj = get_github_auth_token()['token_obj'] + repo = GitHubRepository(token_obj.get_repo(repo_url)) return repo if 'gitlab' in parsed_url.netloc: host = parsed_url.scheme + '://' + parsed_url.netloc From 7c236b5a678b01995f1ac67f7e3133829accffaf Mon Sep 17 00:00:00 2001 From: Naveen <172697+naveensrinivasan@users.noreply.github.com> Date: Tue, 12 Jan 2021 18:17:36 -0500 Subject: [PATCH 017/172] Create codeql-analysis.yml --- .github/workflows/codeql-analysis.yml | 67 +++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 .github/workflows/codeql-analysis.yml diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml new file mode 100644 index 00000000..33ed4975 --- /dev/null +++ b/.github/workflows/codeql-analysis.yml @@ -0,0 +1,67 @@ +# For most projects, this workflow file will not need changing; you simply need +# to commit it to your repository. +# +# You may wish to alter this file to override the set of languages analyzed, +# or to provide custom queries or build logic. +# +# ******** NOTE ******** +# We have attempted to detect the languages in your repository. Please check +# the `language` matrix defined below to confirm you have the correct set of +# supported CodeQL languages. +# +name: "CodeQL" + +on: + push: + branches: [ main ] + pull_request: + # The branches below must be a subset of the branches above + branches: [ main ] + schedule: + - cron: '36 22 * * 3' + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + + strategy: + fail-fast: false + matrix: + language: [ 'python' ] + # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] + # Learn more: + # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed + + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + # Initializes the CodeQL tools for scanning. + - name: Initialize CodeQL + uses: github/codeql-action/init@v1 + with: + languages: ${{ matrix.language }} + # If you wish to specify custom queries, you can do so here or in a config file. + # By default, queries listed here will override any specified in a config file. + # Prefix the list here with "+" to use these queries and those in the config file. + # queries: ./path/to/local/query, your-org/your-repo/queries@main + + # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). + # If this step fails, then you should remove it and run the build manually (see below) + - name: Autobuild + uses: github/codeql-action/autobuild@v1 + + # ℹ️ Command-line programs to run using the OS shell. + # 📚 https://git.io/JvXDl + + # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines + # and modify them (or add more) to build your code if your project + # uses a compiled language + + #- run: | + # make bootstrap + # make release + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v1 From 7f3540971f73f933caa163af9d2ac3e6ce7a41bd Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 16 Jan 2021 19:24:09 +0300 Subject: [PATCH 018/172] - Keep min_wait_time, revert the rest --- criticality_score/generate.py | 2 +- criticality_score/run.py | 85 +++++++++++++++-------------------- 2 files changed, 37 insertions(+), 50 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 1523f90f..a3ad7b55 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -65,7 +65,7 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): # +100 to avoid any races with star updates. query += f' stars:<{last_stars_processed+100}' logger.info(f'Running query: {query}') - token_obj = run.get_github_auth_token()['token_obj'] + token_obj = run.get_github_auth_token() new_result = False repo = None for repo in token_obj.search_repositories(query=query, diff --git a/criticality_score/run.py b/criticality_score/run.py index 005e622e..14642a67 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -31,7 +31,7 @@ from .constants import * # pylint: disable=wildcard-import _CACHED_GITHUB_TOKEN = None -_CACHED_GITHUB_TOKENS = [] +_CACHED_GITHUB_TOKEN_OBJ = None PARAMS = [ 'created_since', 'updated_since', 'contributor_count', 'org_count', @@ -143,8 +143,7 @@ def _parse_links(response): links[match.group(2)] = match.group(1) return links - token = _CACHED_GITHUB_TOKEN['token'] - headers = {'Authorization': f'token {token}'} + headers = {'Authorization': f'token {_CACHED_GITHUB_TOKEN}'} for i in range(FAIL_RETRIES): result = requests.get(f'{self._repo.url}/commits', headers=headers) links = _parse_links(result) @@ -461,54 +460,43 @@ def _worker(repo, param, return_dict): return result_dict -def get_github_auth_token_info(auth_token): - """If near expiry, sets reset information given a github token.""" - rate_limit = auth_token['token_obj'].get_rate_limit() - if rate_limit.core.remaining < 50: - auth_token['reset'] = rate_limit.core.reset - +def get_github_token_info(token_obj): + """Return expiry information given a github token.""" + rate_limit = token_obj.get_rate_limit() + near_expiry = rate_limit.core.remaining < 50 + wait_time = (rate_limit.core.reset - datetime.datetime.utcnow()).seconds + return near_expiry, wait_time + def get_github_auth_token(): """Return an un-expired github token if possible from a list of tokens.""" global _CACHED_GITHUB_TOKEN - - # Initialize _CACHED_GITHUB_TOKENS that stores token, token_obj and reset data as a list - if not _CACHED_GITHUB_TOKENS: - github_auth_token = os.getenv('GITHUB_AUTH_TOKEN') - assert github_auth_token, 'GITHUB_AUTH_TOKEN needs to be set.' # TODO Validate earlier? - for token in github_auth_token.split(','): - token_obj = github.Github(token) - _CACHED_GITHUB_TOKENS.append({ 'token': token, 'token_obj': token_obj, 'reset': None }) - - while True: - # If there's an active token that's not near expiry, use that one - if _CACHED_GITHUB_TOKEN: - get_github_auth_token_info(_CACHED_GITHUB_TOKEN) - if not _CACHED_GITHUB_TOKEN['reset']: - return _CACHED_GITHUB_TOKEN - - # Else, search for the next token - for item in _CACHED_GITHUB_TOKENS: - if item['reset']: # Ignore already expired tokens - continue - - get_github_auth_token_info(item) - if not item['reset']: - _CACHED_GITHUB_TOKEN = item - return item - - # If all tokens are expired, find the minimum wait_time, clear the variables & sleep - wait_time = None - for item in _CACHED_GITHUB_TOKENS: - diff = (item['reset'] - datetime.datetime.utcnow()).seconds + 5 - if not wait_time or diff < wait_time: - wait_time = diff - item['reset'] = None - _CACHED_GITHUB_TOKEN = None - - print(f'Rate limit exceeded. Sleeping till reset: {round((wait_time / 60), 1)} minutes.', - file=sys.stderr) - time.sleep(wait_time) + global _CACHED_GITHUB_TOKEN_OBJ + if _CACHED_GITHUB_TOKEN_OBJ: + near_expiry, _ = get_github_token_info(_CACHED_GITHUB_TOKEN_OBJ) + if not near_expiry: + return _CACHED_GITHUB_TOKEN_OBJ + + github_auth_token = os.getenv('GITHUB_AUTH_TOKEN') + assert github_auth_token, 'GITHUB_AUTH_TOKEN needs to be set.' + tokens = github_auth_token.split(',') + + min_wait_time = None + token_obj = None + for token in tokens: + token_obj = github.Github(token) + near_expiry, wait_time = get_github_token_info(token_obj) + if not min_wait_time or wait_time < min_wait_time: + min_wait_time = wait_time + if not near_expiry: + _CACHED_GITHUB_TOKEN = token + _CACHED_GITHUB_TOKEN_OBJ = token_obj + return token_obj + + print(f'Rate limit exceeded, sleeping till reset: {round(min_wait_time / 60, 1)} minutes.', + file=sys.stderr) + time.sleep(min_wait_time) + return token_obj def get_gitlab_auth_token(host): @@ -532,8 +520,7 @@ def get_repository(url): parsed_url = urllib.parse.urlparse(url) repo_url = parsed_url.path.strip('/') if parsed_url.netloc.endswith('github.com'): - token_obj = get_github_auth_token()['token_obj'] - repo = GitHubRepository(token_obj.get_repo(repo_url)) + repo = GitHubRepository(get_github_auth_token().get_repo(repo_url)) return repo if 'gitlab' in parsed_url.netloc: host = parsed_url.scheme + '://' + parsed_url.netloc From 20cb96ed8345a6e744ed4abbc64aebe2d9b3326e Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 16 Jan 2021 19:43:15 +0300 Subject: [PATCH 019/172] Add .ropeproject folder to gitignore --- .gitignore | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index ba0430d2..13727aa8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ -__pycache__/ \ No newline at end of file +# Byte-compiled / optimized / DLL files +__pycache__/ + +# Rope project settings +.ropeproject From a8debe463d0d0c597c18ee93e59285c9149bcc8e Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 16 Jan 2021 11:20:41 -0800 Subject: [PATCH 020/172] Remove course from ignore list Fixes https://github.com/ossf/criticality_score/issues/75 --- criticality_score/generate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index a3ad7b55..8ac15175 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -37,7 +37,7 @@ 'rust': ['Rust'], 'shell': ['Shell'], } -IGNORED_KEYWORDS = ['course', 'docs', 'interview', 'tutorial'] +IGNORED_KEYWORDS = ['docs', 'interview', 'tutorial'] def get_github_repo_urls(sample_size, languages): urls = [] From a21771b63630569c3e838413c6f1ff378c5dd731 Mon Sep 17 00:00:00 2001 From: Nuthan Munaiah Date: Wed, 3 Feb 2021 02:24:34 -0500 Subject: [PATCH 021/172] Add description of a correlation analysis The correlation analysis is to empirically evaluate the assertion that the criticality score of a repository is merely a proxy for its popularity. --- popularity_correlation.md | 53 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 popularity_correlation.md diff --git a/popularity_correlation.md b/popularity_correlation.md new file mode 100644 index 00000000..dc7089ce --- /dev/null +++ b/popularity_correlation.md @@ -0,0 +1,53 @@ +# Is Criticality Score a Proxy for Popularity? + +In the [Hacker News Discussion](https://news.ycombinator.com/item?id=25381397) about finding Critical open source projects, certain comments [1,2,3] alleged that the criticality score assigned to a project is merely a proxy for its popularity. The assertions are not without merit; a cursory review of the [dataset](https://github.com/ossf/criticality_score#public-data) produced by the Open Source Project Criticality Score program seems to indicate that the most popular projects also have a high cricticality score. For instance, popular projects like git, mono, tensorflow, kubernetes, spark, webpack, symfony, scikit-learn, rails, rust, and oss-fuzz have high critical scores (mean criticality score is 0.9125). + +We wanted to evaluate if criticality score is indeed a proxy for popularity. If the evaluation yields evidence to support this assertion, then the criticality score of a project is likely a redundant measure in the presence of the popularity of the project. + +## Methodology + +We evaluated the correlation between the criticality score of a repository and its popularity (quantified using GitHub Stargazers). The subsections that follow contain specifics of the evaluation methodology. + +### Data + +The 2,200 repositories (200 repositories in each of the 11 programming languages) with criticality scores in the [dataset](https://github.com/ossf/criticality_score#public-data) produced by the Open Source Project Criticality Score program are the subjects of study in this evaluation. We used the GitHub REST API to collect1 the number of stargazers for these 2,200 repositories. + +1Number of stargazers for all repositories was collected on January 20, 2021. + +### Analysis + +We used the Spearman's Rank Correlation Coefficient (ρ) to quantify the correlation between criticality score and number of stargazers. We used the Spearman's Rank Correlation Coefficient because the criticality score and number of stargazers were found (through the Shapiro-Wilk Test) to not follow a Normal Distribution. + +## Results + +The correlation between the criticality score of a repository and its popularity is shown in the Table below. + +| Language | ρ | Effect | p | Significant | +|------------|----------|----------|-------------|-------------| +| Rust | 0.417577 | Moderate | 7.6612E-10 | Yes | +| Ruby | 0.404109 | Moderate | 2.9531E-09 | Yes | +| C# | 0.382657 | Moderate | 2.2452E-08 | Yes | +| JavaScript | 0.368158 | Moderate | 8.1631E-08 | Yes | +| Java | 0.337799 | Moderate | 9.9907E-07 | Yes | +| C++ | 0.321293 | Moderate | 3.5030E-06 | Yes | +| PHP | 0.287965 | Weak | 3.5521E-05 | Yes | +| Go | 0.284187 | Weak | 4.5382E-05 | Yes | +| C | 0.255176 | Weak | 2.6567E-04 | Yes | +| Shell | 0.222957 | Weak | 1.5068E-03 | Yes | +| Python | 0.169501 | Weak | 1.6419E-02 | Yes | + +As can be inferred from the Spearman's ρ (and the corresponding interpretation of the effect), criticality score of a repository is positively correlated with its popularity but the effect is not as strong as some of the comments [1,2,3] from the Hacker News Discussion seem to suggest. + +> All statistical tests were run using `scipy` v1.6. + +## Interpretation + +Although some popular repositories tend to have correspondingly high criticality score, there are counter examples that warrant the need for the computation of the criticality score. + +# References + +[1] "The methodology is pretty silly. It rewards activity and popularity." https://news.ycombinator.com/item?id=25385795 + +[2] "I like this idea, which pops up here and there occasionally, but this particular "criticality score" appears to measure popularity, rather than criticality." https://news.ycombinator.com/item?id=25385562 + +[3] "I may have misread but the fatal error in the metric to me is that popularity of a project increases its criticality when it should decrease." https://news.ycombinator.com/item?id=25388443 \ No newline at end of file From ce5e13abdab355dab95e4ca54b724e9668ede0f2 Mon Sep 17 00:00:00 2001 From: Nuthan Munaiah Date: Wed, 3 Feb 2021 02:30:24 -0500 Subject: [PATCH 022/172] Format table of results --- popularity_correlation.md | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/popularity_correlation.md b/popularity_correlation.md index dc7089ce..34fe1e8d 100644 --- a/popularity_correlation.md +++ b/popularity_correlation.md @@ -22,19 +22,19 @@ We used the Spearman's Rank Correlation Coefficient (ρ) to quantify the correla The correlation between the criticality score of a repository and its popularity is shown in the Table below. -| Language | ρ | Effect | p | Significant | -|------------|----------|----------|-------------|-------------| -| Rust | 0.417577 | Moderate | 7.6612E-10 | Yes | -| Ruby | 0.404109 | Moderate | 2.9531E-09 | Yes | -| C# | 0.382657 | Moderate | 2.2452E-08 | Yes | -| JavaScript | 0.368158 | Moderate | 8.1631E-08 | Yes | -| Java | 0.337799 | Moderate | 9.9907E-07 | Yes | -| C++ | 0.321293 | Moderate | 3.5030E-06 | Yes | -| PHP | 0.287965 | Weak | 3.5521E-05 | Yes | -| Go | 0.284187 | Weak | 4.5382E-05 | Yes | -| C | 0.255176 | Weak | 2.6567E-04 | Yes | -| Shell | 0.222957 | Weak | 1.5068E-03 | Yes | -| Python | 0.169501 | Weak | 1.6419E-02 | Yes | +| Language | ρ | Effect | p | Significant | +| ---------- | -----: | -------- | ---------: | :---------: | +| Rust | 0.4176 | Moderate | 7.6612E-10 | Yes | +| Ruby | 0.4041 | Moderate | 2.9531E-09 | Yes | +| C# | 0.3827 | Moderate | 2.2452E-08 | Yes | +| JavaScript | 0.3682 | Moderate | 8.1631E-08 | Yes | +| Java | 0.3378 | Moderate | 9.9907E-07 | Yes | +| C++ | 0.3213 | Moderate | 3.5030E-06 | Yes | +| PHP | 0.2880 | Weak | 3.5521E-05 | Yes | +| Go | 0.2842 | Weak | 4.5382E-05 | Yes | +| C | 0.2552 | Weak | 2.6567E-04 | Yes | +| Shell | 0.2230 | Weak | 1.5068E-03 | Yes | +| Python | 0.1695 | Weak | 1.6419E-02 | Yes | As can be inferred from the Spearman's ρ (and the corresponding interpretation of the effect), criticality score of a repository is positively correlated with its popularity but the effect is not as strong as some of the comments [1,2,3] from the Hacker News Discussion seem to suggest. From 54089e28f96c573d72e1bbf864df0c2212ba7a3c Mon Sep 17 00:00:00 2001 From: Nuthan Munaiah Date: Wed, 3 Feb 2021 02:31:04 -0500 Subject: [PATCH 023/172] Remove `Significant` column from results --- popularity_correlation.md | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/popularity_correlation.md b/popularity_correlation.md index 34fe1e8d..0e76d7cb 100644 --- a/popularity_correlation.md +++ b/popularity_correlation.md @@ -22,19 +22,21 @@ We used the Spearman's Rank Correlation Coefficient (ρ) to quantify the correla The correlation between the criticality score of a repository and its popularity is shown in the Table below. -| Language | ρ | Effect | p | Significant | -| ---------- | -----: | -------- | ---------: | :---------: | -| Rust | 0.4176 | Moderate | 7.6612E-10 | Yes | -| Ruby | 0.4041 | Moderate | 2.9531E-09 | Yes | -| C# | 0.3827 | Moderate | 2.2452E-08 | Yes | -| JavaScript | 0.3682 | Moderate | 8.1631E-08 | Yes | -| Java | 0.3378 | Moderate | 9.9907E-07 | Yes | -| C++ | 0.3213 | Moderate | 3.5030E-06 | Yes | -| PHP | 0.2880 | Weak | 3.5521E-05 | Yes | -| Go | 0.2842 | Weak | 4.5382E-05 | Yes | -| C | 0.2552 | Weak | 2.6567E-04 | Yes | -| Shell | 0.2230 | Weak | 1.5068E-03 | Yes | -| Python | 0.1695 | Weak | 1.6419E-02 | Yes | +| Language | ρ | Effect | p | +| ---------- | -----: | -------- | ---------: | +| Rust | 0.4176 | Moderate | 7.6612E-10 | +| Ruby | 0.4041 | Moderate | 2.9531E-09 | +| C# | 0.3827 | Moderate | 2.2452E-08 | +| JavaScript | 0.3682 | Moderate | 8.1631E-08 | +| Java | 0.3378 | Moderate | 9.9907E-07 | +| C++ | 0.3213 | Moderate | 3.5030E-06 | +| PHP | 0.2880 | Weak | 3.5521E-05 | +| Go | 0.2842 | Weak | 4.5382E-05 | +| C | 0.2552 | Weak | 2.6567E-04 | +| Shell | 0.2230 | Weak | 1.5068E-03 | +| Python | 0.1695 | Weak | 1.6419E-02 | + +> p values statistically significant at significance level (α) of 0.05. As can be inferred from the Spearman's ρ (and the corresponding interpretation of the effect), criticality score of a repository is positively correlated with its popularity but the effect is not as strong as some of the comments [1,2,3] from the Hacker News Discussion seem to suggest. From c70da58aa117d016fac5d4d80ea1fa2fc089bae9 Mon Sep 17 00:00:00 2001 From: Yikun Jiang Date: Fri, 5 Feb 2021 17:19:27 +0800 Subject: [PATCH 024/172] Fix regex to cover '1 commit result' case Current regex doesn't cover '1 commit result' case, that means if we get only 1 commit result, the dependent number will be set to 0. This patch try to fix it by use '* commit result' to match 'n commit results' and '1 commit result' case. --- criticality_score/constants.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/criticality_score/constants.py b/criticality_score/constants.py index a492bce6..349af37c 100644 --- a/criticality_score/constants.py +++ b/criticality_score/constants.py @@ -45,4 +45,4 @@ FAIL_RETRIES = 7 # Regex to match dependents count. -DEPENDENTS_REGEX = re.compile(b'.*[^0-9,]([0-9,]+).*commit results', re.DOTALL) +DEPENDENTS_REGEX = re.compile(b'.*[^0-9,]([0-9,]+).*commit result', re.DOTALL) From 96958d653e75688801f4abb538e70449deb12ebd Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 6 Feb 2021 17:50:56 +0300 Subject: [PATCH 025/172] Handle not found cases --- criticality_score/generate.py | 3 +++ criticality_score/run.py | 21 +++++++++++++++++---- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 8ac15175..0363820b 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -143,6 +143,9 @@ def main(): for _ in range(3): try: repo = run.get_repository(repo_url) + if not repo: + logger.error(f'Repo not found: {repo_url}') + break output = run.get_repository_stats(repo) break except Exception as exp: diff --git a/criticality_score/run.py b/criticality_score/run.py index c7f48351..47ccaeb7 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -523,14 +523,24 @@ def get_repository(url): parsed_url = urllib.parse.urlparse(url) repo_url = parsed_url.path.strip('/') if parsed_url.netloc.endswith('github.com'): - repo = GitHubRepository(get_github_auth_token().get_repo(repo_url)) - return repo + repo = None + try: + repo = get_github_auth_token().get_repo(repo_url) + except github.GithubException as exp: + if exp.status == 404: + return None + return GitHubRepository(repo) if 'gitlab' in parsed_url.netloc: + repo = None host = parsed_url.scheme + '://' + parsed_url.netloc token_obj = get_gitlab_auth_token(host) repo_url_encoded = urllib.parse.quote_plus(repo_url) - repo = GitLabRepository(token_obj.projects.get(repo_url_encoded)) - return repo + try: + repo = token_obj.projects.get(repo_url_encoded) + except gitlab.exceptions.GitlabGetError as exp: + if exp.response_code == 404: + return None + return GitLabRepository(repo) raise Exception('Unsupported url!') @@ -557,6 +567,9 @@ def main(): args = parser.parse_args() repo = get_repository(args.repo) + if not repo: + print(f'Repo not found: {args.repo}', file=sys.stderr) + return output = get_repository_stats(repo, args.params) if args.format == 'default': for key, value in output.items(): From 64788a1cf6346cc2814f5d13fd32b21ccc29c5fb Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 6 Feb 2021 19:01:34 +0300 Subject: [PATCH 026/172] Fix pylint messages --- criticality_score/generate.py | 5 ++--- criticality_score/run.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 8ac15175..981b8bc1 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -17,7 +17,6 @@ import csv import logging import os -import sys import time from . import run @@ -41,7 +40,7 @@ def get_github_repo_urls(sample_size, languages): urls = [] - if (languages): + if languages: for lang in languages: lang = lang.lower() for github_lang in LANGUAGE_SEARCH_MAP.get(lang, lang): @@ -99,7 +98,7 @@ def initialize_logging_handlers(output_dir): console = logging.StreamHandler() console.setLevel(logging.INFO) - logging.getLogger('').addHandler(console) + logging.getLogger('').addHandler(console) def main(): parser = argparse.ArgumentParser( diff --git a/criticality_score/run.py b/criticality_score/run.py index c7f48351..06525fef 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -456,7 +456,7 @@ def _worker(repo, param, return_dict): DEPENDENTS_COUNT_WEIGHT)) + additional_params_score) / total_weight, 5) - # Make sure score between 0 (least-critical) and 1 (most-critical). + # Make sure score between 0 (least-critical) and 1 (most-critical). criticality_score = max(min(criticality_score, 1), 0) result_dict['criticality_score'] = criticality_score From 39e50b0b21d1ed9156083f410a8b018b1cb9872a Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 6 Feb 2021 20:56:13 +0300 Subject: [PATCH 027/172] Add logger to run script --- criticality_score/run.py | 26 +++++++++++++++++++------- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index c7f48351..2c812bd7 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -17,6 +17,7 @@ import csv import datetime import json +import logging import math import os import sys @@ -30,6 +31,8 @@ from .constants import * # pylint: disable=wildcard-import +logger = logging.getLogger() + _CACHED_GITHUB_TOKEN = None _CACHED_GITHUB_TOKEN_OBJ = None @@ -393,8 +396,7 @@ def get_repository_stats(repo, additional_params=None): int(i) for i in additional_param.split(':') ] except ValueError: - print('Parameter value in bad format: ' + additional_param, - file=sys.stderr) + logger.error('Parameter value in bad format: ' + additional_param) sys.exit(1) additional_params_total_weight += weight additional_params_score += get_param_score(value, max_threshold, @@ -496,8 +498,7 @@ def get_github_auth_token(): _CACHED_GITHUB_TOKEN_OBJ = token_obj return token_obj - print(f'Rate limit exceeded, sleeping till reset: {round(min_wait_time / 60, 1)} minutes.', - file=sys.stderr) + logger.warning(f'Rate limit exceeded, sleeping till reset: {round(min_wait_time / 60, 1)} minutes.') time.sleep(min_wait_time) return token_obj @@ -509,7 +510,7 @@ def get_gitlab_auth_token(host): token_obj = gitlab.Gitlab(host, gitlab_auth_token) token_obj.auth() except gitlab.exceptions.GitlabAuthenticationError: - print("Auth token didn't work, trying un-authenticated. " + logger.info("Auth token didn't work, trying un-authenticated. " "Some params like comment_frequency will not work.") token_obj = gitlab.Gitlab(host) return token_obj @@ -535,6 +536,15 @@ def get_repository(url): raise Exception('Unsupported url!') +def initialize_logging_handlers(): + logging.basicConfig(level=logging.INFO) + logging.getLogger('').handlers.clear() + + console = logging.StreamHandler() + console.setLevel(logging.INFO) + logging.getLogger('').addHandler(console) + + def main(): parser = argparse.ArgumentParser( description='Gives criticality score for an open source project') @@ -555,14 +565,16 @@ def main(): help='Additional parameters in form ::', required=False) + initialize_logging_handlers() + args = parser.parse_args() repo = get_repository(args.repo) output = get_repository_stats(repo, args.params) if args.format == 'default': for key, value in output.items(): - print(f'{key}: {value}') + logger.info(f'{key}: {value}') elif args.format == 'json': - print(json.dumps(output, indent=4)) + logger.info(json.dumps(output, indent=4)) elif args.format == 'csv': csv_writer = csv.writer(sys.stdout) csv_writer.writerow(output.keys()) From af0d346663efdf0fa9864dee9abab936e2fd9fef Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 6 Feb 2021 21:11:57 +0300 Subject: [PATCH 028/172] Replace print with logger.error --- criticality_score/run.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index c734ff8d..72988b51 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -580,7 +580,7 @@ def main(): args = parser.parse_args() repo = get_repository(args.repo) if not repo: - print(f'Repo not found: {args.repo}', file=sys.stderr) + logger.error(f'Repo not found: {args.repo}') return output = get_repository_stats(repo, args.params) if args.format == 'default': From d1270a8e95c991d2763283ab4462268e0b3d07b1 Mon Sep 17 00:00:00 2001 From: Yikun Jiang Date: Sat, 6 Feb 2021 11:40:10 +0800 Subject: [PATCH 029/172] Add page query retries when no match When we do search on related commits of specific repo_name in github, we perhaps get 200 status_code but no right page result, then get an unexpected 0 result accidently. This patch breaks retry loop only when result is 200 status with match result rather than only 200 status. --- criticality_score/run.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index c7f48351..e26d9e67 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -98,6 +98,7 @@ def comment_frequency(self): def dependents_count(self): # TODO: Take package manager dependency trees into account. If we decide # to replace this, then find a solution for C/C++ as well. + match = None parsed_url = urllib.parse.urlparse(self.url) repo_name = parsed_url.path.strip('/') dependents_url = ( @@ -107,9 +108,11 @@ def dependents_count(self): result = requests.get(dependents_url) if result.status_code == 200: content = result.content - break + match = DEPENDENTS_REGEX.match(content) + # Break only when get 200 status with match result + if match: + break time.sleep(2**i) - match = DEPENDENTS_REGEX.match(content) if not match: return 0 return int(match.group(1).replace(b',', b'')) From abb7f26a8ed19f43b5a876c8e9cf6592968956c3 Mon Sep 17 00:00:00 2001 From: coni2k Date: Wed, 10 Feb 2021 23:19:49 +0300 Subject: [PATCH 030/172] Update Readme file --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c1ce3a4d..a217c938 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ source control systems. ```shell $ gsutil ls gs://ossf-criticality-score/*.csv +gs://ossf-criticality-score/all.csv gs://ossf-criticality-score/c_top_200.csv gs://ossf-criticality-score/cplusplus_top_200.csv gs://ossf-criticality-score/csharp_top_200.csv From 9bd552e27f930d8d812470ebe1c1233868b7e164 Mon Sep 17 00:00:00 2001 From: coni2k Date: Wed, 10 Feb 2021 23:40:03 +0300 Subject: [PATCH 031/172] Update all.csv text --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a217c938..5c3c9efe 100644 --- a/README.md +++ b/README.md @@ -125,7 +125,6 @@ source control systems. ```shell $ gsutil ls gs://ossf-criticality-score/*.csv -gs://ossf-criticality-score/all.csv gs://ossf-criticality-score/c_top_200.csv gs://ossf-criticality-score/cplusplus_top_200.csv gs://ossf-criticality-score/csharp_top_200.csv @@ -149,6 +148,7 @@ $ python3 -u -m criticality_score.generate \ --language c --count 200 --sample-size 5000 --output-dir output ``` +We have aggregated the results over 100K repositories in GitHub (language-independent) and are available for download [here](https://www.googleapis.com/download/storage/v1/b/ossf-criticality-score/o/all.csv?generation=1612987910088811&alt=media). ## Contributing From 9e4e1451ed508d90c1f762d13ca2807e3b6fd5f9 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Wed, 10 Feb 2021 12:45:11 -0800 Subject: [PATCH 032/172] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5c3c9efe..2c034617 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ $ python3 -u -m criticality_score.generate \ --language c --count 200 --sample-size 5000 --output-dir output ``` -We have aggregated the results over 100K repositories in GitHub (language-independent) and are available for download [here](https://www.googleapis.com/download/storage/v1/b/ossf-criticality-score/o/all.csv?generation=1612987910088811&alt=media). +We have also aggregated the results over 100K repositories in GitHub (language-independent) and are available for download [here](https://www.googleapis.com/download/storage/v1/b/ossf-criticality-score/o/all.csv?generation=1612987910088811&alt=media). ## Contributing From 46ce66b6502959d4d5bad96db74d93f6cf9633e9 Mon Sep 17 00:00:00 2001 From: coni2k Date: Thu, 18 Feb 2021 11:16:37 +0300 Subject: [PATCH 033/172] Handle empty repo case --- criticality_score/generate.py | 4 +++- criticality_score/run.py | 8 ++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 1e6f1163..c01ff68e 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -143,7 +143,7 @@ def main(): try: repo = run.get_repository(repo_url) if not repo: - logger.error(f'Repo not found: {repo_url}') + logger.error(f'Repo is empty or not found: {repo_url}') break output = run.get_repository_stats(repo) break @@ -155,6 +155,8 @@ def main(): stats.append(output) index += 1 + if len(stats) == 0: + return languages = '_'.join(args.language) if args.language else 'all' languages = languages.replace('+', 'plus').replace('c#', 'csharp') output_filename = os.path.join(args.output_dir, diff --git a/criticality_score/run.py b/criticality_score/run.py index 066cb84f..a13f0489 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -530,8 +530,10 @@ def get_repository(url): repo = None try: repo = get_github_auth_token().get_repo(repo_url) + # Validate whether repo is empty; if it's empty, calling totalCount throws a 409 exception + total_commits = repo.get_commits().totalCount except github.GithubException as exp: - if exp.status == 404: + if exp.status == 404 or exp.status == 409: return None return GitHubRepository(repo) if 'gitlab' in parsed_url.netloc: @@ -541,6 +543,8 @@ def get_repository(url): repo_url_encoded = urllib.parse.quote_plus(repo_url) try: repo = token_obj.projects.get(repo_url_encoded) + if len(repo.commits.list()) == 0: + return None except gitlab.exceptions.GitlabGetError as exp: if exp.response_code == 404: return None @@ -583,7 +587,7 @@ def main(): args = parser.parse_args() repo = get_repository(args.repo) if not repo: - logger.error(f'Repo not found: {args.repo}') + logger.error(f'Repo is empty or not found: {args.repo}') return output = get_repository_stats(repo, args.params) if args.format == 'default': From 55ec68d6065924de0a3d55f50c8c67ad3e674a9e Mon Sep 17 00:00:00 2001 From: coni2k Date: Sat, 20 Feb 2021 12:21:00 +0300 Subject: [PATCH 034/172] - Add last_commit prop to prevent double API calls - Update empty repo validation --- criticality_score/run.py | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index a13f0489..b96fff02 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -45,8 +45,9 @@ class Repository: """General source repository.""" - def __init__(self, repo): + def __init__(self, repo, last_commit): self._repo = repo + self._last_commit = last_commit self._created_since = None @property @@ -61,6 +62,10 @@ def url(self): def language(self): raise NotImplementedError + @property + def last_commit(self): + raise NotImplementedError + @property def created_since(self): raise NotImplementedError @@ -136,6 +141,10 @@ def url(self): def language(self): return self._repo.language + @property + def last_commit(self): + return self._last_commit + def get_first_commit_time(self): def _parse_links(response): link_string = response.headers.get('Link') @@ -189,8 +198,7 @@ def created_since(self): @property def updated_since(self): - last_commit = self._repo.get_commits()[0] - last_commit_time = last_commit.commit.author.date + last_commit_time = self.last_commit.commit.author.date difference = datetime.datetime.utcnow() - last_commit_time return round(difference.days / 30) @@ -293,6 +301,10 @@ def language(self): languages = self._repo.languages() return (max(languages, key=languages.get)).lower() + @property + def last_commit(self): + return self.last_commit + @property def created_since(self): creation_time = self._date_from_string(self._repo.created_at) @@ -308,10 +320,9 @@ def created_since(self): @property def updated_since(self): - last_commit = self._repo.commits.list()[0] difference = datetime.datetime.now( datetime.timezone.utc) - self._date_from_string( - last_commit.created_at) + self.last_commit.created_at) return round(difference.days / 30) @property @@ -528,27 +539,30 @@ def get_repository(url): repo_url = parsed_url.path.strip('/') if parsed_url.netloc.endswith('github.com'): repo = None + last_commit = None try: repo = get_github_auth_token().get_repo(repo_url) - # Validate whether repo is empty; if it's empty, calling totalCount throws a 409 exception - total_commits = repo.get_commits().totalCount + last_commit = repo.get_commits()[0] except github.GithubException as exp: if exp.status == 404 or exp.status == 409: return None - return GitHubRepository(repo) + return GitHubRepository(repo, last_commit) if 'gitlab' in parsed_url.netloc: repo = None + last_commit = None host = parsed_url.scheme + '://' + parsed_url.netloc token_obj = get_gitlab_auth_token(host) repo_url_encoded = urllib.parse.quote_plus(repo_url) try: repo = token_obj.projects.get(repo_url_encoded) - if len(repo.commits.list()) == 0: + commits = repo.commits.list() + if len(commits) == 0: return None + last_commit = commits[0] except gitlab.exceptions.GitlabGetError as exp: if exp.response_code == 404: return None - return GitLabRepository(repo) + return GitLabRepository(repo, last_commit) raise Exception('Unsupported url!') From 0b0052cc13ca8c7a23050039021ad7928149bf34 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Sun, 21 Feb 2021 15:13:53 +0000 Subject: [PATCH 035/172] Create Dependabot config file --- .github/dependabot.yml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..491deae0 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: +- package-ecosystem: pip + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 From 7c969fc82f6bfa282e81a3bd83d7792d7a4deea1 Mon Sep 17 00:00:00 2001 From: coni2k Date: Mon, 22 Feb 2021 00:31:47 +0300 Subject: [PATCH 036/172] Move last_commit logic inside of the class --- criticality_score/run.py | 41 ++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index b96fff02..fe10a376 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -45,9 +45,9 @@ class Repository: """General source repository.""" - def __init__(self, repo, last_commit): + def __init__(self, repo): self._repo = repo - self._last_commit = last_commit + self._last_commit = None self._created_since = None @property @@ -143,6 +143,9 @@ def language(self): @property def last_commit(self): + if self._last_commit: + return self._last_commit + self._last_commit = self._repo.get_commits()[0] return self._last_commit def get_first_commit_time(self): @@ -303,7 +306,10 @@ def language(self): @property def last_commit(self): - return self.last_commit + if self._last_commit: + return self._last_commit + self._last_commit = self._repo.commits.list()[0] + return self._last_commit @property def created_since(self): @@ -537,35 +543,34 @@ def get_repository(url): parsed_url = urllib.parse.urlparse(url) repo_url = parsed_url.path.strip('/') + repo = None if parsed_url.netloc.endswith('github.com'): - repo = None - last_commit = None try: - repo = get_github_auth_token().get_repo(repo_url) - last_commit = repo.get_commits()[0] + repo_obj = get_github_auth_token().get_repo(repo_url) + repo = GitHubRepository(repo_obj) except github.GithubException as exp: - if exp.status == 404 or exp.status == 409: + if exp.status == 404: return None - return GitHubRepository(repo, last_commit) if 'gitlab' in parsed_url.netloc: - repo = None - last_commit = None host = parsed_url.scheme + '://' + parsed_url.netloc token_obj = get_gitlab_auth_token(host) repo_url_encoded = urllib.parse.quote_plus(repo_url) try: - repo = token_obj.projects.get(repo_url_encoded) - commits = repo.commits.list() - if len(commits) == 0: - return None - last_commit = commits[0] + repo_obj = token_obj.projects.get(repo_url_encoded) + repo = GitLabRepository(repo_obj) except gitlab.exceptions.GitlabGetError as exp: if exp.response_code == 404: return None - return GitLabRepository(repo, last_commit) - raise Exception('Unsupported url!') + if not repo: + raise Exception('Unsupported url!') + try: + if not repo.last_commit: + return None + except Exception: + return None + return repo def initialize_logging_handlers(): logging.basicConfig(level=logging.INFO) From 5b9784c8d2d41e7c8e30a13579051891727f54cb Mon Sep 17 00:00:00 2001 From: coni2k Date: Mon, 22 Feb 2021 01:10:08 +0300 Subject: [PATCH 037/172] Move the validation to get_repository_stats --- criticality_score/generate.py | 4 +++- criticality_score/run.py | 30 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 15 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index c01ff68e..b4fc47cd 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -143,9 +143,11 @@ def main(): try: repo = run.get_repository(repo_url) if not repo: - logger.error(f'Repo is empty or not found: {repo_url}') + logger.error(f'Repo is not found: {repo_url}') break output = run.get_repository_stats(repo) + if not output: + logger.error(f'Repo is empty: {repo_url}') break except Exception as exp: logger.exception(f'Exception occurred when reading repo: {repo_url}\n{exp}') diff --git a/criticality_score/run.py b/criticality_score/run.py index fe10a376..2409f76d 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -406,6 +406,11 @@ def get_param_score(param, max_value, weight=1): def get_repository_stats(repo, additional_params=None): """Return repository stats, including criticality score.""" # Validate and compute additional params first. + try: + if not repo.last_commit: + return None + except Exception: + return None if additional_params is None: additional_params = [] additional_params_total_weight = 0 @@ -543,34 +548,28 @@ def get_repository(url): parsed_url = urllib.parse.urlparse(url) repo_url = parsed_url.path.strip('/') - repo = None if parsed_url.netloc.endswith('github.com'): + repo = None try: - repo_obj = get_github_auth_token().get_repo(repo_url) - repo = GitHubRepository(repo_obj) + repo = get_github_auth_token().get_repo(repo_url) except github.GithubException as exp: if exp.status == 404: return None + return GitHubRepository(repo) if 'gitlab' in parsed_url.netloc: + repo = None host = parsed_url.scheme + '://' + parsed_url.netloc token_obj = get_gitlab_auth_token(host) repo_url_encoded = urllib.parse.quote_plus(repo_url) try: - repo_obj = token_obj.projects.get(repo_url_encoded) - repo = GitLabRepository(repo_obj) + repo = token_obj.projects.get(repo_url_encoded) except gitlab.exceptions.GitlabGetError as exp: if exp.response_code == 404: return None + return GitLabRepository(repo) - if not repo: - raise Exception('Unsupported url!') + raise Exception('Unsupported url!') - try: - if not repo.last_commit: - return None - except Exception: - return None - return repo def initialize_logging_handlers(): logging.basicConfig(level=logging.INFO) @@ -606,9 +605,12 @@ def main(): args = parser.parse_args() repo = get_repository(args.repo) if not repo: - logger.error(f'Repo is empty or not found: {args.repo}') + logger.error(f'Repo is not found: {args.repo}') return output = get_repository_stats(repo, args.params) + if not output: + logger.error(f'Repo is empty: {args.repo}') + return if args.format == 'default': for key, value in output.items(): logger.info(f'{key}: {value}') From 4d210477154abaa9c9d0a23bae5cebfdd74cd04b Mon Sep 17 00:00:00 2001 From: coni2k Date: Mon, 22 Feb 2021 10:54:54 +0300 Subject: [PATCH 038/172] - Move error messages to the validation block - Move try/catch block to GitHub last_commit - Prevent exception for GitLab last_commit --- criticality_score/generate.py | 2 -- criticality_score/run.py | 14 +++++++------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index b4fc47cd..f546ee04 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -146,8 +146,6 @@ def main(): logger.error(f'Repo is not found: {repo_url}') break output = run.get_repository_stats(repo) - if not output: - logger.error(f'Repo is empty: {repo_url}') break except Exception as exp: logger.exception(f'Exception occurred when reading repo: {repo_url}\n{exp}') diff --git a/criticality_score/run.py b/criticality_score/run.py index 2409f76d..3c1f68eb 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -145,7 +145,10 @@ def language(self): def last_commit(self): if self._last_commit: return self._last_commit - self._last_commit = self._repo.get_commits()[0] + try: + self._last_commit = self._repo.get_commits()[0] + except Exception: + pass return self._last_commit def get_first_commit_time(self): @@ -308,7 +311,7 @@ def language(self): def last_commit(self): if self._last_commit: return self._last_commit - self._last_commit = self._repo.commits.list()[0] + self._last_commit = next(iter(self._repo.commits.list()), None) return self._last_commit @property @@ -406,10 +409,8 @@ def get_param_score(param, max_value, weight=1): def get_repository_stats(repo, additional_params=None): """Return repository stats, including criticality score.""" # Validate and compute additional params first. - try: - if not repo.last_commit: - return None - except Exception: + if not repo.last_commit: + logger.error(f'Repo is empty: {repo.url}') return None if additional_params is None: additional_params = [] @@ -609,7 +610,6 @@ def main(): return output = get_repository_stats(repo, args.params) if not output: - logger.error(f'Repo is empty: {args.repo}') return if args.format == 'default': for key, value in output.items(): From 8101f96280e2ed9c6e3a96d78cb558cdc8fac0c2 Mon Sep 17 00:00:00 2001 From: coni2k Date: Sun, 28 Feb 2021 16:43:10 +0300 Subject: [PATCH 039/172] Handle get_tags exception --- criticality_score/run.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index 3c1f68eb..71054491 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -255,7 +255,11 @@ def recent_releases_count(self): days_since_creation = self.created_since * 30 if not days_since_creation: return 0 - total_tags = self._repo.get_tags().totalCount + total_tags = 0 + try: + total_tags = self._repo.get_tags().totalCount + except Exception: + logger.error(f'get_tags is failed: {self._repo.url}') total = round( (total_tags / days_since_creation) * RELEASE_LOOKBACK_DAYS) return total From 7d7dbab53157706faed2fc504cffcdbba1b76361 Mon Sep 17 00:00:00 2001 From: coni2k Date: Mon, 1 Mar 2021 00:41:23 +0300 Subject: [PATCH 040/172] - Add comment for the exception - Return default value --- criticality_score/run.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/criticality_score/run.py b/criticality_score/run.py index 71054491..faa82a71 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -259,7 +259,9 @@ def recent_releases_count(self): try: total_tags = self._repo.get_tags().totalCount except Exception: + # Very large number of tags, i.e. 5000+. Cap at 26. logger.error(f'get_tags is failed: {self._repo.url}') + return RECENT_RELEASES_THRESHOLD total = round( (total_tags / days_since_creation) * RELEASE_LOOKBACK_DAYS) return total From 83eabbd88049f2a678f710481ff3439e82da32f9 Mon Sep 17 00:00:00 2001 From: coni2k Date: Mon, 1 Mar 2021 02:27:59 +0300 Subject: [PATCH 041/172] Update Readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c034617..18f82d6a 100644 --- a/README.md +++ b/README.md @@ -148,7 +148,7 @@ $ python3 -u -m criticality_score.generate \ --language c --count 200 --sample-size 5000 --output-dir output ``` -We have also aggregated the results over 100K repositories in GitHub (language-independent) and are available for download [here](https://www.googleapis.com/download/storage/v1/b/ossf-criticality-score/o/all.csv?generation=1612987910088811&alt=media). +We have also aggregated the results over 100K repositories in GitHub (language-independent) and are available for download [here](https://www.googleapis.com/download/storage/v1/b/ossf-criticality-score/o/all.csv?generation=1614554714813772&alt=media). ## Contributing From d4b1210f74baa967ab446dacc97e3ca91164104c Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 24 Apr 2021 10:43:35 -0700 Subject: [PATCH 042/172] Support generation via github orgs. Also, fix a hang bug when dependents count returns zero result. --- criticality_score/generate.py | 64 +++++++++++++++++++++++++++-------- criticality_score/run.py | 10 +++--- 2 files changed, 55 insertions(+), 19 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index f546ee04..64d8f3b2 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -37,6 +37,8 @@ 'shell': ['Shell'], } IGNORED_KEYWORDS = ['docs', 'interview', 'tutorial'] +DEFAULT_SAMPLE_SIZE = 5000 + def get_github_repo_urls(sample_size, languages): urls = [] @@ -44,12 +46,14 @@ def get_github_repo_urls(sample_size, languages): for lang in languages: lang = lang.lower() for github_lang in LANGUAGE_SEARCH_MAP.get(lang, lang): - urls = get_github_repo_urls_for_language(urls, sample_size, github_lang) + urls = get_github_repo_urls_for_language( + urls, sample_size, github_lang) else: urls = get_github_repo_urls_for_language(urls, sample_size) return urls + def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): """Return repository urls given a language list and sample size.""" samples_processed = 1 @@ -68,8 +72,8 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): new_result = False repo = None for repo in token_obj.search_repositories(query=query, - sort='stars', - order='desc'): + sort='stars', + order='desc'): # Forced sleep to avoid hitting rate limit. time.sleep(0.1) repo_url = repo.html_url @@ -82,7 +86,7 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): urls.append(repo_url) new_result = True logger.info(f'Found repository' - f'({samples_processed}): {repo_url}') + f'({samples_processed}): {repo_url}') samples_processed += 1 if samples_processed > sample_size: break @@ -92,14 +96,31 @@ def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): return urls + +def get_github_repo_urls_for_orgs(orgs): + """Return repository urls given a org list""" + repo_urls = set() + for org in orgs: + token_obj = run.get_github_auth_token() + token_org = token_obj.get_organization(org) + repos = token_org.get_repos() + for repo in repos: + repo_urls.add(repo.html_url) + + return repo_urls + + def initialize_logging_handlers(output_dir): log_filename = os.path.join(output_dir, 'output.log') - logging.basicConfig(filename=log_filename, filemode='w', level=logging.INFO) + logging.basicConfig(filename=log_filename, + filemode='w', + level=logging.INFO) console = logging.StreamHandler() console.setLevel(logging.INFO) logging.getLogger('').addHandler(console) + def main(): parser = argparse.ArgumentParser( description= @@ -116,24 +137,36 @@ def main(): help="Directory to place the output in.") parser.add_argument("--count", type=int, - default=200, + default=10000, help="Number of projects in result.") parser.add_argument( "--sample-size", type=int, - default=5000, help="Number of projects to analyze (in descending order of stars).") + parser.add_argument("--org", + nargs='+', + default=[], + required=False, + help="List of organizations for populating the repos.") args = parser.parse_args() initialize_logging_handlers(args.output_dir) - # GitHub search can return incomplete results in a query, so try it multiple - # times to avoid missing urls. repo_urls = set() - for rnd in range(1, 4): - logger.info(f'Finding repos (round {rnd}):') - repo_urls.update(get_github_repo_urls(args.sample_size, args.language)) + if args.org: + assert not args.language, 'Languages is not supported with orgs.' + assert not args.sample_size, 'Sample size is not supported with orgs.' + repo_urls.update(get_github_repo_urls_for_orgs(args.org)) + else: + if not args.sample_size: + args.sample_size = DEFAULT_SAMPLE_SIZE + # GitHub search can return incomplete results in a query, so try it + # multiple times to avoid missing urls. + for rnd in range(1, 4): + logger.info(f'Finding repos (round {rnd}):') + repo_urls.update( + get_github_repo_urls(args.sample_size, args.language)) stats = [] index = 1 @@ -148,10 +181,13 @@ def main(): output = run.get_repository_stats(repo) break except Exception as exp: - logger.exception(f'Exception occurred when reading repo: {repo_url}\n{exp}') + logger.exception( + f'Exception occurred when reading repo: {repo_url}\n{exp}') if not output: continue - logger.info(f"{index} - {output['name']} - {output['url']} - {output['criticality_score']}") + logger.info( + f"{index} - {output['name']} - {output['url']} - {output['criticality_score']}" + ) stats.append(output) index += 1 diff --git a/criticality_score/run.py b/criticality_score/run.py index faa82a71..5accca02 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -117,9 +117,7 @@ def dependents_count(self): if result.status_code == 200: content = result.content match = DEPENDENTS_REGEX.match(content) - # Break only when get 200 status with match result - if match: - break + break time.sleep(2**i) if not match: return 0 @@ -530,7 +528,9 @@ def get_github_auth_token(): _CACHED_GITHUB_TOKEN_OBJ = token_obj return token_obj - logger.warning(f'Rate limit exceeded, sleeping till reset: {round(min_wait_time / 60, 1)} minutes.') + logger.warning( + f'Rate limit exceeded, sleeping till reset: {round(min_wait_time / 60, 1)} minutes.' + ) time.sleep(min_wait_time) return token_obj @@ -543,7 +543,7 @@ def get_gitlab_auth_token(host): token_obj.auth() except gitlab.exceptions.GitlabAuthenticationError: logger.info("Auth token didn't work, trying un-authenticated. " - "Some params like comment_frequency will not work.") + "Some params like comment_frequency will not work.") token_obj = gitlab.Gitlab(host) return token_obj From f8cc096963f06b971881e67689fcaa8c17600587 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 24 Apr 2021 13:24:47 -0700 Subject: [PATCH 043/172] Fix a hang bug with few commits repo. --- criticality_score/generate.py | 7 +++---- criticality_score/run.py | 14 +++++++------- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 64d8f3b2..39567539 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -170,7 +170,7 @@ def main(): stats = [] index = 1 - for repo_url in repo_urls: + for repo_url in sorted(repo_urls): output = None for _ in range(3): try: @@ -185,9 +185,8 @@ def main(): f'Exception occurred when reading repo: {repo_url}\n{exp}') if not output: continue - logger.info( - f"{index} - {output['name']} - {output['url']} - {output['criticality_score']}" - ) + logger.info(f"{index} - {output['name']} - {output['url']} - " + f"{output['criticality_score']}") stats.append(output) index += 1 diff --git a/criticality_score/run.py b/criticality_score/run.py index 5accca02..9cc87c7d 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -168,13 +168,13 @@ def _parse_links(response): links = _parse_links(result) if links and links.get('last'): result = requests.get(links['last'], headers=headers) - if result.status_code == 200: - commits = json.loads(result.content) - if commits: - last_commit_time_string = ( - commits[-1]['commit']['committer']['date']) - return datetime.datetime.strptime( - last_commit_time_string, "%Y-%m-%dT%H:%M:%SZ") + if result.status_code == 200: + commits = json.loads(result.content) + if commits: + last_commit_time_string = ( + commits[-1]['commit']['committer']['date']) + return datetime.datetime.strptime(last_commit_time_string, + "%Y-%m-%dT%H:%M:%SZ") time.sleep(2**i) return None From 3460bb0878872dcdea1619c58cb46910ebce9884 Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sun, 25 Apr 2021 13:11:24 -0700 Subject: [PATCH 044/172] Use auth header when doing dependents query, avoid rate limit. --- criticality_score/run.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index 9cc87c7d..13534b66 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -102,6 +102,13 @@ def closed_issues_count(self): def comment_frequency(self): raise NotImplementedError + def _request_url_with_auth_headers(self, url): + headers = {} + if 'github.com' in url and _CACHED_GITHUB_TOKEN: + headers = {'Authorization': f'token {_CACHED_GITHUB_TOKEN}'} + + return requests.get(url, headers=headers) + @property def dependents_count(self): # TODO: Take package manager dependency trees into account. If we decide @@ -111,12 +118,10 @@ def dependents_count(self): repo_name = parsed_url.path.strip('/') dependents_url = ( f'https://github.com/search?q="{repo_name}"&type=commits') - content = b'' for i in range(FAIL_RETRIES): - result = requests.get(dependents_url) + result = self._request_url_with_auth_headers(dependents_url) if result.status_code == 200: - content = result.content - match = DEPENDENTS_REGEX.match(content) + match = DEPENDENTS_REGEX.match(result.content) break time.sleep(2**i) if not match: @@ -162,12 +167,12 @@ def _parse_links(response): links[match.group(2)] = match.group(1) return links - headers = {'Authorization': f'token {_CACHED_GITHUB_TOKEN}'} for i in range(FAIL_RETRIES): - result = requests.get(f'{self._repo.url}/commits', headers=headers) + result = self._request_url_with_auth_headers( + f'{self._repo.url}/commits') links = _parse_links(result) if links and links.get('last'): - result = requests.get(links['last'], headers=headers) + result = self._request_url_with_auth_headers(links['last']) if result.status_code == 200: commits = json.loads(result.content) if commits: From c41ab0f27cd63fb058f8c296dd3a804ddc4c93e6 Mon Sep 17 00:00:00 2001 From: Dilan Date: Tue, 3 Aug 2021 17:54:46 -0700 Subject: [PATCH 045/172] adding watchers/description metrics --- README.md | 20 +++++++++++--------- criticality_score/run.py | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 18f82d6a..d017bede 100644 --- a/README.md +++ b/README.md @@ -52,17 +52,19 @@ $ criticality_score --repo github.com/kubernetes/kubernetes name: kubernetes url: https://github.com/kubernetes/kubernetes language: Go -created_since: 79 +description: Production-Grade Container Scheduling and Management +created_since: 87 updated_since: 0 -contributor_count: 3664 +contributor_count: 3999 +watchers_count: 79583 org_count: 5 -commit_frequency: 102.7 -recent_releases_count: 76 -closed_issues_count: 2906 -updated_issues_count: 5136 -comment_frequency: 5.7 -dependents_count: 407254 -criticality_score: 0.9862 +commit_frequency: 97.2 +recent_releases_count: 70 +updated_issues_count: 5395 +closed_issues_count: 3062 +comment_frequency: 5.5 +dependents_count: 454393 +criticality_score: 0.99107 ``` You can add your own parameters to the criticality score calculation. For diff --git a/criticality_score/run.py b/criticality_score/run.py index 13534b66..e00ce19f 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -37,7 +37,7 @@ _CACHED_GITHUB_TOKEN_OBJ = None PARAMS = [ - 'created_since', 'updated_since', 'contributor_count', 'org_count', + 'description', 'created_since', 'updated_since', 'contributor_count', 'watchers_count', 'org_count', 'commit_frequency', 'recent_releases_count', 'updated_issues_count', 'closed_issues_count', 'comment_frequency', 'dependents_count' ] @@ -62,6 +62,10 @@ def url(self): def language(self): raise NotImplementedError + @property + def description(self): + raise NotImplementedError + @property def last_commit(self): raise NotImplementedError @@ -78,6 +82,10 @@ def updated_since(self): def contributor_count(self): raise NotImplementedError + @property + def watchers_count(self): + raise NotImplementedError + @property def org_count(self): raise NotImplementedError @@ -144,6 +152,10 @@ def url(self): def language(self): return self._repo.language + @property + def description(self): + return self._repo.description + @property def last_commit(self): if self._last_commit: @@ -219,6 +231,10 @@ def contributor_count(self): # Very large number of contributors, i.e. 5000+. Cap at 5,000. return 5000 + @property + def watchers_count(self): + return self._repo.watchers_count + @property def org_count(self): def _filter_name(org_name): From bff25a86288032effa8abc95e6371eef04dce684 Mon Sep 17 00:00:00 2001 From: i2z1 Date: Fri, 3 Dec 2021 15:21:39 +0300 Subject: [PATCH 046/172] add support for R language --- criticality_score/generate.py | 1 + 1 file changed, 1 insertion(+) diff --git a/criticality_score/generate.py b/criticality_score/generate.py index 39567539..6b467ef1 100644 --- a/criticality_score/generate.py +++ b/criticality_score/generate.py @@ -35,6 +35,7 @@ 'ruby': ['Ruby'], 'rust': ['Rust'], 'shell': ['Shell'], + 'r': ['R'], } IGNORED_KEYWORDS = ['docs', 'interview', 'tutorial'] DEFAULT_SAMPLE_SIZE = 5000 From 1cc9cf27efcc1b88a55d1b69a1aa572cac5b8b73 Mon Sep 17 00:00:00 2001 From: Arnaud J Le Hors Date: Wed, 30 Mar 2022 21:39:22 +0200 Subject: [PATCH 047/172] Allow overriding default parameters Adds a command line parameter to override the weight and threshold of the build-in parameters. Signed-off-by: Arnaud J Le Hors --- README.md | 13 +++- .../{constants.py => defaults.py} | 2 +- criticality_score/run.py | 66 ++++++++++++++++++- 3 files changed, 77 insertions(+), 4 deletions(-) rename criticality_score/{constants.py => defaults.py} (96%) diff --git a/README.md b/README.md index d017bede..179dfe44 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ by [Rob Pike](https://github.com/robpike): -We use the following parameters to derive the criticality score for an +We use the following default parameters to derive the criticality score for an open source project: | Parameter (Si) | Weight (αi) | Max threshold (Ti) | Description | Reasoning | @@ -38,6 +38,7 @@ open source project: **NOTE**: +- You can override those defaut values at runtime as described below. - We are looking for community ideas to improve upon these parameters. - There will always be exceptions to the individual reasoning rules. @@ -71,7 +72,15 @@ You can add your own parameters to the criticality score calculation. For example, you can add internal project usage data to re-adjust the project's criticality score for your prioritization needs. This can be done by adding the `--params :: ...` -argument on the command line. +argument on the command line. You cannot specify the parameter names and +these won't be listed in the results but they will be included in the +score calculation. + +You can override the default values for the weight and threshold of the +built-in parameters to match your needs. This can be done by adding the +`--overrides :: ...` +argument on the command line, where param1_name refers to the name of the +parameter you want to override. ### Authentication diff --git a/criticality_score/constants.py b/criticality_score/defaults.py similarity index 96% rename from criticality_score/constants.py rename to criticality_score/defaults.py index 349af37c..93ea0bcd 100644 --- a/criticality_score/constants.py +++ b/criticality_score/defaults.py @@ -11,7 +11,7 @@ # 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. -"""Constants used in OSS criticality score calculation.""" +"""Defaults used in OSS criticality score calculation.""" import re # Weights for various parameters. diff --git a/criticality_score/run.py b/criticality_score/run.py index e00ce19f..d0046057 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -29,7 +29,7 @@ import gitlab import requests -from .constants import * # pylint: disable=wildcard-import +from .defaults import * # pylint: disable=wildcard-import logger = logging.getLogger() @@ -608,6 +608,62 @@ def initialize_logging_handlers(): logging.getLogger('').addHandler(console) +def override_params(override_params): + for override_param in override_params: + temp = override_param.split(':',1) + param_name = temp[0] + try: + weight, threshold = [ + float(i) for i in temp[1].split(':') + ] + except ValueError: + logger.error('Override parameter in bad format: ' + override_param) + sys.exit(1) + if param_name == 'created_since': + global CREATED_SINCE_WEIGHT, CREATED_SINCE_THRESHOLD + CREATED_SINCE_WEIGHT = weight + CREATED_SINCE_THRESHOLD = threshold + elif param_name == 'updated_since': + global UPDATED_SINCE_WEIGHT, UPDATED_SINCE_THRESHOLD + UPDATED_SINCE_WEIGHT = weight + UPDATED_SINCE_THRESHOLD = threshold + elif param_name == 'contributor_count': + global CONTRIBUTOR_COUNT_WEIGHT, CONTRIBUTOR_COUNT_THRESHOLD + CONTRIBUTOR_COUNT_WEIGHT = weight + CONTRIBUTOR_COUNT_THRESHOLD = threshold + elif param_name == 'org_count': + global ORG_COUNT_WEIGHT, ORG_COUNT_THRESHOLD + ORG_COUNT_WEIGHT = weight + ORG_COUNT_THRESHOLD = threshold + elif param_name == 'commit_frequency': + global COMMIT_FREQUENCY_WEIGHT, COMMIT_FREQUENCY_THRESHOLD + COMMIT_FREQUENCY_WEIGHT = weight + COMMIT_FREQUENCY_THRESHOLD = threshold + elif param_name == 'recent_releases_count': + global RECENT_RELEASES_WEIGHT, RECENT_RELEASES_THRESHOLD + RECENT_RELEASES_WEIGHT = weight + RECENT_RELEASES_THRESHOLD = threshold + elif param_name == 'updated_issues_count': + global UPDATED_ISSUES_WEIGHT, UPDATED_ISSUES_THRESHOLD + UPDATED_ISSUES_WEIGHT = weight + UPDATED_ISSUES_THRESHOLD = threshold + elif param_name == 'closed_issues_count': + global CLOSED_ISSUES_WEIGHT, CLOSED_ISSUES_THRESHOLD + CLOSED_ISSUES_WEIGHT = weight + CLOSED_ISSUES_THRESHOLD = threshold + elif param_name == 'comment_frequency': + global COMMENT_FREQUENCY_WEIGHT, COMMENT_FREQUENCY_THRESHOLD + COMMENT_FREQUENCY_WEIGHT = weight + COMMENT_FREQUENCY_THRESHOLD = threshold + elif param_name == 'dependents_count': + global DEPENDENTS_COUNT_WEIGHT, DEPENDENTS_COUNT_THRESHOLD + DEPENDENTS_COUNT_WEIGHT = weight + DEPENDENTS_COUNT_THRESHOLD = threshold + else: + raise Exception( + 'Wrong format argument, unknown parameter: ' + param_name) + + def main(): parser = argparse.ArgumentParser( description='Gives criticality score for an open source project') @@ -627,10 +683,18 @@ def main(): default=[], help='Additional parameters in form ::', required=False) + parser.add_argument( + '--overrides', + nargs='+', + default=[], + help='Overriding parameters in form ::', + required=False) initialize_logging_handlers() args = parser.parse_args() + if args.overrides: + override_params(args.overrides) repo = get_repository(args.repo) if not repo: logger.error(f'Repo is not found: {args.repo}') From 482de7043a45992302bf393f0e9c7471e1c2cda1 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 13 Apr 2022 10:19:24 +1000 Subject: [PATCH 048/172] Add a command for enumerating GitHub repos (written in Go) (#111) Takes the algorithms suggested in #33 and combines them to allow approx repos with at least 10 stars and higher to be enumerated. This approach *only* collects project URLs. There are other sources of data that can be used such as GH Archive, GHTorrent, etc to compliment this list. All the project URLs found can eventually be de-duped, checked for existance (e.g. 404s), canonicalized, and then used for signal collection. --- cmd/enumerate_github/githubsearch/repos.go | 153 ++++ cmd/enumerate_github/githubsearch/search.go | 43 + cmd/enumerate_github/main.go | 238 +++++ cmd/enumerate_github/pagination/pagination.go | 86 ++ go.mod | 42 + go.sum | 810 ++++++++++++++++++ 6 files changed, 1372 insertions(+) create mode 100644 cmd/enumerate_github/githubsearch/repos.go create mode 100644 cmd/enumerate_github/githubsearch/search.go create mode 100644 cmd/enumerate_github/main.go create mode 100644 cmd/enumerate_github/pagination/pagination.go create mode 100644 go.mod create mode 100644 go.sum diff --git a/cmd/enumerate_github/githubsearch/repos.go b/cmd/enumerate_github/githubsearch/repos.go new file mode 100644 index 00000000..1990b3b1 --- /dev/null +++ b/cmd/enumerate_github/githubsearch/repos.go @@ -0,0 +1,153 @@ +package githubsearch + +import ( + "fmt" + + "github.com/ossf/criticality_score/cmd/enumerate_github/pagination" + "github.com/shurcooL/githubv4" +) + +// repo is part of the GitHub GraphQL query and includes the fields +// that will be populated in a response. +type repo struct { + StargazerCount int + Url string +} + +// repoQuery is a GraphQL query for iterating over repositories in GitHub +type repoQuery struct { + Search struct { + RepositoryCount int + Nodes []struct { + Repository repo `graphql:"...on Repository"` + } + PageInfo struct { + HasNextPage bool + EndCursor string + } + } `graphql:"search(type: REPOSITORY, query: $query, first: $perPage, after: $endCursor)"` +} + +// Total implements the pagination.PagedQuery interface +func (q *repoQuery) Total() int { + return q.Search.RepositoryCount +} + +// Length implements the pagination.PagedQuery interface +func (q *repoQuery) Length() int { + return len(q.Search.Nodes) +} + +// Get implements the pagination.PagedQuery interface +func (q *repoQuery) Get(i int) interface{} { + return q.Search.Nodes[i].Repository +} + +// HasNextPage implements the pagination.PagedQuery interface +func (q *repoQuery) HasNextPage() bool { + return q.Search.PageInfo.HasNextPage +} + +// NextPageVars implements the pagination.PagedQuery interface +func (q *repoQuery) NextPageVars() map[string]interface{} { + if q.Search.PageInfo.EndCursor == "" { + return map[string]interface{}{ + "endCursor": (*githubv4.String)(nil), + } + } else { + return map[string]interface{}{ + "endCursor": githubv4.String(q.Search.PageInfo.EndCursor), + } + } +} + +func buildQuery(q string, minStars, maxStars int) string { + q = q + " sort:stars " + if maxStars > 0 { + return q + fmt.Sprintf("stars:%d..%d", minStars, maxStars) + } else { + return q + fmt.Sprintf("stars:>=%d", minStars) + } +} + +func (re *Searcher) runRepoQuery(q string) (*pagination.Cursor, error) { + re.logger.V(1).Info("Searching GitHub", "query", q) + vars := map[string]interface{}{ + "query": githubv4.String(q), + "perPage": githubv4.Int(re.perPage), + } + return pagination.Query(re.ctx, re.client, &repoQuery{}, vars) +} + +// ReposByStars will call emitter once for each repository returned when searching for baseQuery +// with at least minStars, order from the most stars, to the least. +// +// The emitter function is called with the repository's Url. +// +// The algorithm works to overcome the approx 1000 repository limit returned by a single search +// across 10 pages by: +// - Ordering GitHub's repositories from most stars to least. +// - Iterating through all the repositories returned by each query. +// - Getting the number of stars for the last repository returned. +// - Using this star value, plus an overlap, to be the maximum star limit. +// +// The algorithm fails if the last star value plus overlap has the same or larger value as the +// previous iteration. +func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, emitter func(string)) error { + repos := make(map[string]struct{}) + maxStars := -1 + stars := 0 + for { + q := buildQuery(baseQuery, minStars, maxStars) + c, err := re.runRepoQuery(q) + if err != nil { + return err + } + + total := c.Total() + seen := 0 + stars = 0 + for !c.Finished() { + obj, err := c.Next() + if err != nil { + return err + } + repo := obj.(repo) + seen++ + stars = repo.StargazerCount + if _, ok := repos[repo.Url]; !ok { + repos[repo.Url] = empty{} + emitter(repo.Url) + } + } + remaining := total - seen + re.logger.V(1).Info( + "Finished iterating through results", + "total_available", total, + "total_returned", seen, + "total_remaining", remaining, + "unique_repos", len(repos), + "last_stars", stars, + "query", q, + ) + newMaxStars := stars + overlap + if remaining <= 0 { + break + } else if maxStars == -1 || newMaxStars < maxStars { + maxStars = newMaxStars + } else { + // the gap between "stars" and "maxStars" is less than "overlap", so we can't + // safely step any lower without skipping stars. + re.logger.Error( + ErrorUnableToListAllResult, + "Too many repositories for current range", + "min_stars", minStars, + "stars", stars, + "max_stars", maxStars, + "overlap", overlap, + ) + return ErrorUnableToListAllResult + } + } + return nil +} diff --git a/cmd/enumerate_github/githubsearch/search.go b/cmd/enumerate_github/githubsearch/search.go new file mode 100644 index 00000000..5d5be001 --- /dev/null +++ b/cmd/enumerate_github/githubsearch/search.go @@ -0,0 +1,43 @@ +package githubsearch + +import ( + "context" + "errors" + + "github.com/go-logr/logr" + "github.com/shurcooL/githubv4" +) + +// empty is a convenience wrapper for the empty struct. +type empty struct{} + +var ErrorUnableToListAllResult = errors.New("unable to list all results") + +type Searcher struct { + ctx context.Context + client *githubv4.Client + logger logr.Logger + perPage int +} + +type Option interface{ set(*Searcher) } +type option func(*Searcher) // option implements Option. +func (o option) set(s *Searcher) { o(s) } + +// PerPage will set how many results will per requested per page for each search query. +func PerPage(perPage int) Option { + return option(func(s *Searcher) { s.perPage = perPage }) +} + +func NewSearcher(ctx context.Context, client *githubv4.Client, logger logr.Logger, options ...Option) *Searcher { + s := &Searcher{ + ctx: ctx, + client: client, + logger: logger, + perPage: 100, + } + for _, o := range options { + o.set(s) + } + return s +} diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go new file mode 100644 index 00000000..0f32c862 --- /dev/null +++ b/cmd/enumerate_github/main.go @@ -0,0 +1,238 @@ +package main + +import ( + "context" + "errors" + "flag" + "fmt" + "net/http" + "os" + "path" + "sync" + "time" + + "github.com/go-logr/logr" + "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" + "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" + "github.com/ossf/scorecard/v4/log" + "github.com/shurcooL/githubv4" +) + +const ( + githubDateFormat = "2006-01-02" + reposPerPage = 100 + oneDay = time.Hour * 24 +) + +var ( + // epochDate is the earliest date for which GitHub has data. + epochDate = time.Date(2008, 1, 1, 0, 0, 0, 0, time.UTC) + + forceFlag = flag.Bool("force", false, "overwrites FILE if it already exists and -append is not set.") + appendFlag = flag.Bool("append", false, "appends to FILE if it already exists.") + minStarsFlag = flag.Int("min-stars", 10, "only enumerates repositories with this or more of stars.") + starOverlapFlag = flag.Int("star-overlap", 5, "the number of stars to overlap between queries.") + requireMinStarsFlag = flag.Bool("require-min-stars", false, "abort if -min-stars can't be reached during enumeration.") + queryFlag = flag.String("query", "is:public", "sets the base query to use for enumeration.") + workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") + startDateFlag = dateFlag(epochDate) + endDateFlag = dateFlag(time.Now().UTC().Truncate(oneDay)) + logFlag = logLevelFlag(log.DefaultLevel) +) + +// dateFlag implements the flag.Value interface to simplify the input and validation of +// dates from the command line. +type dateFlag time.Time + +func (d *dateFlag) Set(value string) error { + t, err := time.Parse(githubDateFormat, value) + if err != nil { + return err + } + *d = dateFlag(t) + return nil +} + +func (d *dateFlag) String() string { + return (*time.Time)(d).Format(githubDateFormat) +} + +func (d *dateFlag) Time() time.Time { + return (time.Time)(*d) +} + +// logLevelFlag implements the flag.Value interface to simplify the input and validation +// of the current log level. +type logLevelFlag log.Level + +func (l *logLevelFlag) Set(value string) error { + *l = logLevelFlag(log.ParseLevel(value)) + return nil +} + +func (l logLevelFlag) String() string { + return string(log.Level(l)) +} + +func (l logLevelFlag) Level() log.Level { + return log.Level(l) +} + +func init() { + flag.Var(&startDateFlag, "start", "the start `date` to enumerate back to. Must be at or after 2008-01-01.") + flag.Var(&endDateFlag, "end", "the end `date` to enumerate from.") + flag.Var(&logFlag, "log", "set the `level` of logging.") + flag.Usage = func() { + cmdName := path.Base(os.Args[0]) + w := flag.CommandLine.Output() + fmt.Fprintf(w, "Usage:\n %s [FLAGS]... FILE\n\n", cmdName) + fmt.Fprintf(w, "Enumerates GitHub repositories between -start date and -end date, with -min-stars\n") + fmt.Fprintf(w, "or higher. Writes each repository URL on a separate line to FILE.\n") + fmt.Fprintf(w, "\nFlags:\n") + flag.PrintDefaults() + } +} + +// searchWorker waits for a query on the queries channel, starts a search with that query using s +// and returns each repository on the results channel. +// +// When the queries channel is closed it will call wg.Done() to signal that the worker has finished. +func searchWorker(s *githubsearch.Searcher, wg *sync.WaitGroup, logger logr.Logger, queries, results chan string) { + defer wg.Done() + for q := range queries { + total := 0 + err := s.ReposByStars(q, *minStarsFlag, *starOverlapFlag, func(repo string) { + results <- repo + total++ + }) + if err != nil { + // TODO: this error handling is not at all graceful, and hard to recover from. + logger.Error(err, "Enumeration failed for query", "query", q) + if errors.Is(err, githubsearch.ErrorUnableToListAllResult) { + if *requireMinStarsFlag { + os.Exit(1) + } + } else { + os.Exit(1) + } + } + logger.Info("Enumeration for query done", "query", q, "repo_count", total) + } +} + +func main() { + flag.Parse() + + // roundtripper requires us to use the scorecard logger. + // TODO: try and replace this with logrus directly. + logger := log.NewLogger(logFlag.Level()) + + // Ensure the -start date is not before the epoch. + if startDateFlag.Time().Before(epochDate) { + logger.Error(nil, fmt.Sprintf("-start date must be no earlier than %s", epochDate.Format(githubDateFormat))) + os.Exit(2) + } + + // Ensure -start is before -end + if endDateFlag.Time().Before(startDateFlag.Time()) { + logger.Error(nil, "-start date must be before -end date") + os.Exit(2) + } + + // Ensure a non-flag argument (the output file) is specified. + if flag.NArg() != 1 { + logger.Error(nil, "An output file must be specified.") + os.Exit(2) + } + outFilename := flag.Arg(0) + + // Print a helpful message indicating the configuration we're using. + logger.Info( + "Preparing output file", + "filename", outFilename, + "force", *forceFlag, + "append", *appendFlag) + + // Open the output file based on the flags + // TODO: support '-' to use os.Stdout. + var out *os.File + var err error + if *appendFlag { + out, err = os.OpenFile(outFilename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|os.O_APPEND, 0666) + } else if *forceFlag { + out, err = os.OpenFile(outFilename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|os.O_TRUNC, 0666) + } else { + out, err = os.OpenFile(outFilename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|os.O_EXCL, 0666) + } + if err != nil { + // file failed to open + panic(err) + } + defer out.Close() + + logger.Info( + "Starting enumeration", + "start", startDateFlag.String(), + "end", endDateFlag.String(), + "min_stars", *minStarsFlag, + "star_overlap", *starOverlapFlag, + "workers", *workersFlag, + ) + + // Track how long it takes to enumerate the repositories + startTime := time.Now() + ctx := context.Background() + + // Prepare a client for communicating with GitHub's GraphQL API + rt := roundtripper.NewTransport(ctx, logger) + httpClient := &http.Client{ + Transport: rt, + } + client := githubv4.NewClient(httpClient) + + baseQuery := *queryFlag + var wg sync.WaitGroup + wg.Add(*workersFlag) + queries := make(chan string) + results := make(chan string, (*workersFlag)*reposPerPage) + + // Start the worker goroutines to execute the search queries + for i := 0; i < *workersFlag; i++ { + workerLogger := logger.WithValues("worker", i) + s := githubsearch.NewSearcher(ctx, client, workerLogger, githubsearch.PerPage(reposPerPage)) + go searchWorker(s, &wg, workerLogger, queries, results) + } + + // Start a separate goroutine to collect results so worker output is always consumed. + done := make(chan bool) + totalRepos := 0 + go func() { + for repo := range results { + fmt.Fprintln(out, repo) + totalRepos++ + } + done <- true + }() + + // Work happens here. Iterate through the dates from today, until the start date. + for created := endDateFlag.Time(); !startDateFlag.Time().After(created); created = created.Add(-oneDay) { + logger.Info("Scheduling day for enumeration", "created", created.Format(githubDateFormat)) + queries <- baseQuery + fmt.Sprintf(" created:%s", created.Format(githubDateFormat)) + } + logger.V(1).Info("Waiting for workers to finish") + // Indicate to the workers that we're finished. + close(queries) + // Wait for the workers to be finished. + wg.Wait() + + logger.V(1).Info("Waiting for writer to finish") + // Close the results channel now the workers are done. + close(results) + // Wait for the writer to be finished. + <-done + + logger.Info( + "Finished enumeration", + "total_repos", totalRepos, + "duration", time.Now().Sub(startTime).Truncate(time.Minute).String()) +} diff --git a/cmd/enumerate_github/pagination/pagination.go b/cmd/enumerate_github/pagination/pagination.go new file mode 100644 index 00000000..f98b15c8 --- /dev/null +++ b/cmd/enumerate_github/pagination/pagination.go @@ -0,0 +1,86 @@ +package pagination + +import ( + "context" + "io" + + "github.com/shurcooL/githubv4" +) + +// PagedQuery implementors go from being regular query struct passed to githubv4.Query() +// to a query that can be paginated. +type PagedQuery interface { + Total() int + Length() int + Get(int) interface{} + HasNextPage() bool + NextPageVars() map[string]interface{} +} + +type Cursor struct { + ctx context.Context + client *githubv4.Client + query PagedQuery + vars map[string]interface{} + cur int +} + +func Query(ctx context.Context, client *githubv4.Client, query PagedQuery, vars map[string]interface{}) (*Cursor, error) { + c := &Cursor{ + ctx: ctx, + client: client, + query: query, + vars: vars, + } + if err := c.queryNextPage(); err != nil { + return nil, err + } + return c, nil +} + +func (c *Cursor) queryNextPage() error { + // Merge the next page vars with the current vars + newVars := c.query.NextPageVars() + for k, v := range newVars { + c.vars[k] = v + } + // Reset the current position + c.cur = 0 + // Execute the query + return c.client.Query(c.ctx, c.query, c.vars) +} + +func (c *Cursor) atEndOfPage() bool { + return c.cur >= c.query.Length() +} + +func (c *Cursor) isLastPage() bool { + return !c.query.HasNextPage() +} + +func (c *Cursor) Finished() bool { + return c.atEndOfPage() && c.isLastPage() +} + +func (c *Cursor) Total() int { + return c.query.Total() +} + +func (c *Cursor) Next() (interface{}, error) { + if c.Finished() { + // We've finished so return an EOF + return nil, io.EOF + } else if c.atEndOfPage() { + // We're at the end of the page, but not finished, so grab the next page. + if err := c.queryNextPage(); err != nil { + return nil, err + } + // Make sure we didn't get an empty result. + if c.atEndOfPage() { + return nil, io.EOF + } + } + val := c.query.Get(c.cur) + c.cur++ + return val, nil +} diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..239796fc --- /dev/null +++ b/go.mod @@ -0,0 +1,42 @@ +module github.com/ossf/criticality_score + +go 1.18 + +require ( + github.com/go-logr/logr v1.2.2 + github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 +) + +require ( + cloud.google.com/go v0.100.2 // indirect + cloud.google.com/go/compute v0.1.0 // indirect + cloud.google.com/go/iam v0.1.1 // indirect + cloud.google.com/go/storage v1.18.2 // indirect + github.com/bombsimon/logrusr/v2 v2.0.1 // indirect + github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect + github.com/golang-jwt/jwt/v4 v4.0.0 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.7 // indirect + github.com/google/go-github/v38 v38.1.0 // indirect + github.com/google/go-github/v41 v41.0.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/wire v0.5.0 // indirect + github.com/googleapis/gax-go/v2 v2.1.1 // indirect + github.com/ossf/scorecard/v4 v4.1.0 // indirect + github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect + github.com/sirupsen/logrus v1.8.1 // indirect + go.opencensus.io v0.23.0 // indirect + gocloud.dev v0.24.0 // indirect + golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect + golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect + golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect + google.golang.org/api v0.67.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00 // indirect + google.golang.org/grpc v1.44.0 // indirect + google.golang.org/protobuf v1.27.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..b1ad137d --- /dev/null +++ b/go.sum @@ -0,0 +1,810 @@ +bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.88.0/go.mod h1:dnKwfYbP9hQhefiUvpbcAyoGSHUrOxR20JVElLiUvEY= +cloud.google.com/go v0.89.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.92.2/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.92.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.0/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= +cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/compute v0.1.0 h1:rSUBvAyVwNJ5uQCKNJFMwPtTvJkfN38b6Pvb9zZoqJ8= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.5.0/go.mod h1:c4nNYR1qdq7eaZ+jSc5fonrQN2k3M7sWATcYTiakjEo= +cloud.google.com/go/iam v0.1.1 h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68= +cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= +cloud.google.com/go/kms v0.1.0/go.mod h1:8Qp8PCAypHg4FdmlyW1QRAv09BGQ9Uzh7JnmIZxPk+c= +cloud.google.com/go/monitoring v0.1.0/go.mod h1:Hpm3XfzJv+UTiXzCG5Ffp0wijzHTC7Cv4eR7o3x/fEE= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.16.0/go.mod h1:6A8EfoWZ/lUvCWStKGwAWauJZSiuV0Mkmu6WilK/TxQ= +cloud.google.com/go/secretmanager v0.1.0/go.mod h1:3nGKHvnzDUVit7U0S9KAKJ4aOsO1xtwRG+7ey5LK1bM= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.16.1/go.mod h1:LaNorbty3ehnU3rEjXSNV/NRgQA0O8Y+uh6bPe5UOk4= +cloud.google.com/go/storage v1.18.2 h1:5NQw6tOn3eMm0oE8vTkfjau18kjL79FlMjy/CHTpmoY= +cloud.google.com/go/storage v1.18.2/go.mod h1:AiIj7BWXyhO5gGVmYJ+S8tbkCx3yb0IMjua8Aw4naVM= +cloud.google.com/go/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= +contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= +contrib.go.opencensus.io/exporter/stackdriver v0.13.8/go.mod h1:huNtlWx75MwO7qMs0KrMxPZXzNNWebav1Sq/pm02JdQ= +contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-amqp-common-go/v3 v3.1.0/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0= +github.com/Azure/azure-amqp-common-go/v3 v3.1.1/go.mod h1:YsDaPfaO9Ub2XeSKdIy2DfwuiQlHQCauHJwSqtrkECI= +github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= +github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v57.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-service-bus-go v0.10.16/go.mod h1:MlkLwGGf1ewcx5jZadn0gUEty+tTg0RaElr6bPf+QhI= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +github.com/Azure/go-amqp v0.13.0/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs= +github.com/Azure/go-amqp v0.13.11/go.mod h1:D5ZrjQqB1dyp1A+G73xeL/kNn7D5qHJIIsNNps7YNmk= +github.com/Azure/go-amqp v0.13.12/go.mod h1:D5ZrjQqB1dyp1A+G73xeL/kNn7D5qHJIIsNNps7YNmk= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= +github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= +github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.3/go.mod h1:yAQ2b6eP/CmLPnmLvxtT1ALIY3OR1oFcCqVBi8vHiTc= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.24.0/go.mod h1:3tx938GhY4FC+E1KT/jNjDw7Z5qxAEtIiERJ2sXjnII= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.40.34/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= +github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= +github.com/aws/aws-sdk-go-v2/config v1.7.0/go.mod h1:w9+nMZ7soXCe5nT46Ri354SNhXDQ6v+V5wqDjnZE+GY= +github.com/aws/aws-sdk-go-v2/credentials v1.4.0/go.mod h1:dgGR+Qq7Wjcd4AOAW5Rf5Tnv3+x7ed6kETXyS9WCuAY= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.0/go.mod h1:CpNzHK9VEFUCknu50kkB8z58AH2B5DvPP7ea1LHve/Y= +github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2/go.mod h1:BQV0agm+JEhqR+2RT5e1XTFIDcAAV0eW6z2trp+iduw= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0/go.mod h1:R1KK+vY8AfalhG1AOu5e35pOD2SdoPKQCFLTvnxiohk= +github.com/aws/aws-sdk-go-v2/service/kms v1.5.0/go.mod h1:w7JuP9Oq1IKMFQPkNe3V6s9rOssXzOVEMNEqK1L1bao= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0/go.mod h1:B+7C5UKdVq1ylkI/A6O8wcurFtaux0R1njePNPtKwoA= +github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0/go.mod h1:4dXS5YNqI3SNbetQ7X7vfsMlX6ZnboJA2dulBwJx7+g= +github.com/aws/aws-sdk-go-v2/service/sso v1.4.0/go.mod h1:+1fpWnL96DL23aXPpMGbsmKe8jLTEfbjuQoA4WS1VaA= +github.com/aws/aws-sdk-go-v2/service/sts v1.7.0/go.mod h1:0qcSMCyASQPN2sk/1KQLQ2Fh6yq8wm0HSDAimPhzCoM= +github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= +github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= +github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 h1:tXKVfhE7FcSkhkv0UwkLvPDeZ4kz6OXd0PKPlFqf81M= +github.com/bradleyfalzon/ghinstallation/v2 v2.0.4/go.mod h1:B40qPqJxWE0jDZgOR1JmaMy+4AY1eBP+IByOvqyAKp0= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= +github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= +github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= +github.com/google/go-github/v38 v38.1.0 h1:C6h1FkaITcBFK7gAmq4eFzt6gbhEhk7L5z6R3Uva+po= +github.com/google/go-github/v38 v38.1.0/go.mod h1:cStvrz/7nFr0FoENgG6GLbp53WaelXucT+BBz/3VKx4= +github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= +github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= +github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= +github.com/google/go-replayers/httpreplay v1.0.0/go.mod h1:LJhKoTwS5Wy5Ld/peq8dFFG5OfJyHEz7ft+DsTUv25M= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210715191844-86eeefc3e471/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= +github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/ossf/scorecard/v4 v4.1.0 h1:azfb4TQhO79k4u8IK/r0h94OUjewYIpv7waUdqvabeE= +github.com/ossf/scorecard/v4 v4.1.0/go.mod h1:qC9nQPRqMB5Jc77d3Z2KPtjYQkW7o6FbTPTfo7LZOr4= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 h1:82EIpiGB79OIPgSGa63Oj4Ipf+YAX1c6A9qjmEYoRXc= +github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= +github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= +github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= +github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= +github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= +go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= +gocloud.dev v0.24.0 h1:cNtHD07zQQiv02OiwwDyVMuHmR7iQt2RLkzoAgz7wBs= +gocloud.dev v0.24.0/go.mod h1:uA+als++iBX5ShuG4upQo/3Zoz49iIPlYUWHV5mM8w8= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.52.0/go.mod h1:Him/adpjt0sxtkWViy0b6xyKW/SD71CwdJ7HqJo7SrU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= +google.golang.org/api v0.67.0 h1:lYaaLa+x3VVUhtosaK9xihwQ9H9KRa557REHwwZ2orM= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210825212027-de86158e7fda/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00 h1:zmf8Yq9j+IyTpps+paSkmHkSu5fJlRKy69LxRzc17Q0= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From f1f0a5ba43347c3a679756637205c51acd5d7cfa Mon Sep 17 00:00:00 2001 From: CannedFish Liang Date: Wed, 13 Apr 2022 12:01:26 +0800 Subject: [PATCH 049/172] Support for local csv file as input (#106) --- criticality_score/run.py | 168 ++++++++++++++++++++++++++------------- 1 file changed, 112 insertions(+), 56 deletions(-) diff --git a/criticality_score/run.py b/criticality_score/run.py index d0046057..82f8705b 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -431,27 +431,11 @@ def get_param_score(param, max_value, weight=1): return (math.log(1 + param) / math.log(1 + max(param, max_value))) * weight -def get_repository_stats(repo, additional_params=None): - """Return repository stats, including criticality score.""" - # Validate and compute additional params first. +def get_repository_stats(repo): + """Return repository stats by grabing the raw signal data from the repo.""" if not repo.last_commit: logger.error(f'Repo is empty: {repo.url}') return None - if additional_params is None: - additional_params = [] - additional_params_total_weight = 0 - additional_params_score = 0 - for additional_param in additional_params: - try: - value, weight, max_threshold = [ - int(i) for i in additional_param.split(':') - ] - except ValueError: - logger.error('Parameter value in bad format: ' + additional_param) - sys.exit(1) - additional_params_total_weight += weight - additional_params_score += get_param_score(value, max_threshold, - weight) def _worker(repo, param, return_dict): """worker function""" @@ -476,6 +460,28 @@ def _worker(repo, param, return_dict): for param in PARAMS: result_dict[param] = return_dict[param] + return result_dict + + +def get_repository_score(repo_stats, additional_params=None): + """Return one repository's criticality score based on repo stats.""" + # Validate and compute additional params first. + if additional_params is None: + additional_params = [] + additional_params_total_weight = 0 + additional_params_score = 0 + for additional_param in additional_params: + try: + value, weight, max_threshold = [ + float(i) for i in additional_param.split(':') + ] + except ValueError: + logger.error('Parameter value in bad format: ' + additional_param) + sys.exit(1) + additional_params_total_weight += weight + additional_params_score += get_param_score(value, max_threshold, + weight) + total_weight = (CREATED_SINCE_WEIGHT + UPDATED_SINCE_WEIGHT + CONTRIBUTOR_COUNT_WEIGHT + ORG_COUNT_WEIGHT + COMMIT_FREQUENCY_WEIGHT + RECENT_RELEASES_WEIGHT + @@ -484,36 +490,72 @@ def _worker(repo, param, return_dict): additional_params_total_weight) criticality_score = round( - ((get_param_score(result_dict['created_since'], - CREATED_SINCE_THRESHOLD, CREATED_SINCE_WEIGHT)) + - (get_param_score(result_dict['updated_since'], - UPDATED_SINCE_THRESHOLD, UPDATED_SINCE_WEIGHT)) + - (get_param_score(result_dict['contributor_count'], - CONTRIBUTOR_COUNT_THRESHOLD, - CONTRIBUTOR_COUNT_WEIGHT)) + - (get_param_score(result_dict['org_count'], ORG_COUNT_THRESHOLD, - ORG_COUNT_WEIGHT)) + - (get_param_score(result_dict['commit_frequency'], - COMMIT_FREQUENCY_THRESHOLD, - COMMIT_FREQUENCY_WEIGHT)) + - (get_param_score(result_dict['recent_releases_count'], - RECENT_RELEASES_THRESHOLD, RECENT_RELEASES_WEIGHT)) + - (get_param_score(result_dict['closed_issues_count'], - CLOSED_ISSUES_THRESHOLD, CLOSED_ISSUES_WEIGHT)) + - (get_param_score(result_dict['updated_issues_count'], - UPDATED_ISSUES_THRESHOLD, UPDATED_ISSUES_WEIGHT)) + - (get_param_score( - result_dict['comment_frequency'], COMMENT_FREQUENCY_THRESHOLD, - COMMENT_FREQUENCY_WEIGHT)) + (get_param_score( - result_dict['dependents_count'], DEPENDENTS_COUNT_THRESHOLD, - DEPENDENTS_COUNT_WEIGHT)) + additional_params_score) / + ((get_param_score(float(repo_stats['created_since']), + CREATED_SINCE_THRESHOLD, CREATED_SINCE_WEIGHT)) + + (get_param_score(float(repo_stats['updated_since']), + UPDATED_SINCE_THRESHOLD, UPDATED_SINCE_WEIGHT)) + + (get_param_score(float(repo_stats['contributor_count']), + CONTRIBUTOR_COUNT_THRESHOLD, CONTRIBUTOR_COUNT_WEIGHT)) + + (get_param_score(float(repo_stats['org_count']), + ORG_COUNT_THRESHOLD, ORG_COUNT_WEIGHT)) + + (get_param_score(float(repo_stats['commit_frequency']), + COMMIT_FREQUENCY_THRESHOLD, COMMIT_FREQUENCY_WEIGHT)) + + (get_param_score(float(repo_stats['recent_releases_count']), + RECENT_RELEASES_THRESHOLD, RECENT_RELEASES_WEIGHT)) + + (get_param_score(float(repo_stats['closed_issues_count']), + CLOSED_ISSUES_THRESHOLD, CLOSED_ISSUES_WEIGHT)) + + (get_param_score(float(repo_stats['updated_issues_count']), + UPDATED_ISSUES_THRESHOLD, UPDATED_ISSUES_WEIGHT)) + + (get_param_score(float(repo_stats['comment_frequency']), + COMMENT_FREQUENCY_THRESHOLD, COMMENT_FREQUENCY_WEIGHT)) + + (get_param_score(float(repo_stats['dependents_count']), + DEPENDENTS_COUNT_THRESHOLD, DEPENDENTS_COUNT_WEIGHT)) + + additional_params_score) / total_weight, 5) # Make sure score between 0 (least-critical) and 1 (most-critical). criticality_score = max(min(criticality_score, 1), 0) - result_dict['criticality_score'] = criticality_score - return result_dict + return criticality_score + + +def get_repository_score_from_raw_stats(repo_url, params=None): + """Get repository's criticality_score based on raw signal data.""" + repo = get_repository(repo_url) + if repo is None: + logger.error(f'Repo is not found: {repo_url}') + return + repo_stats = get_repository_stats(repo) + repo_stats["criticality_score"] = get_repository_score(repo_stats, params) + + return repo_stats + + +def get_repository_score_from_local_csv(file_path, params=None): + """Get repository's criticality_score based on a local csv file.""" + if params is None: + additional_params = [] + else: + try: + additional_params = [additional_param.split(':') for additional_param in params] + except ValueError: + logger.error('Parameter value in bad format: ' + params) + sys.exit(1) + + output = [] + with open(file_path, "r") as fd: + input_data = csv.DictReader(fd, delimiter=',') + for row in input_data: + logger.debug(row) + + calc_params = [] + for key,weight,max_threshold in additional_params: + calc_params.append(f"{row[key]}:{weight}:{max_threshold}") + + row["criticality_score"] = get_repository_score(row, calc_params) + output.append(row) + + return output def get_github_token_info(token_obj): @@ -581,6 +623,7 @@ def get_repository(url): try: repo = get_github_auth_token().get_repo(repo_url) except github.GithubException as exp: + logger.error(f"Get github repository failed: {exp}") if exp.status == 404: return None return GitHubRepository(repo) @@ -667,10 +710,14 @@ def override_params(override_params): def main(): parser = argparse.ArgumentParser( description='Gives criticality score for an open source project') - parser.add_argument("--repo", + group = parser.add_mutually_exclusive_group(required=True) + group.add_argument("--repo", type=str, - required=True, help="repository url") + group.add_argument("--local-file", + type=str, + dest="l_file", + help="path of a local csv file with repo stats") parser.add_argument( "--format", type=str, @@ -681,7 +728,7 @@ def main(): '--params', nargs='+', default=[], - help='Additional parameters in form ::', + help='Additional parameters in form (|)::, for repo, and for loacl file', required=False) parser.add_argument( '--overrides', @@ -691,16 +738,23 @@ def main(): required=False) initialize_logging_handlers() - args = parser.parse_args() if args.overrides: override_params(args.overrides) - repo = get_repository(args.repo) - if not repo: - logger.error(f'Repo is not found: {args.repo}') - return - output = get_repository_stats(repo, args.params) - if not output: + + output = None + if args.repo: + output = get_repository_score_from_raw_stats(args.repo, args.params) + elif args.l_file: + if args.format != "csv": + logger.error(f"Only support for the format of csv, now is {args.format}") + sys.exit(1) + + output = get_repository_score_from_local_csv(args.l_file, args.params) + else: + raise Exception("Unknown data input type") + + if output is None: return if args.format == 'default': for key, value in output.items(): @@ -708,9 +762,11 @@ def main(): elif args.format == 'json': logger.info(json.dumps(output, indent=4)) elif args.format == 'csv': - csv_writer = csv.writer(sys.stdout) - csv_writer.writerow(output.keys()) - csv_writer.writerow(output.values()) + if args.repo: + output = [output] + csv_writer = csv.DictWriter(sys.stdout, fieldnames=output[0].keys()) + csv_writer.writeheader() + csv_writer.writerows(output) else: raise Exception( 'Wrong format argument, use one of default, csv or json!') From dcefa01387aa47893cb0518b33caa48d0ee32e8f Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 14 Apr 2022 14:23:54 +1000 Subject: [PATCH 050/172] Minor improvements to the github enumeration tool (#112) 1. Update the logging to use logrus directly. Make use of a recent change to scorecard allowing a scorecard logger to be created using an external logrus instance. 2. Remove a final "panic" --- cmd/enumerate_github/githubsearch/repos.go | 37 +- cmd/enumerate_github/githubsearch/search.go | 6 +- cmd/enumerate_github/main.go | 91 +-- go.mod | 33 +- go.sum | 692 +------------------- 5 files changed, 102 insertions(+), 757 deletions(-) diff --git a/cmd/enumerate_github/githubsearch/repos.go b/cmd/enumerate_github/githubsearch/repos.go index 1990b3b1..6632a4b5 100644 --- a/cmd/enumerate_github/githubsearch/repos.go +++ b/cmd/enumerate_github/githubsearch/repos.go @@ -5,6 +5,7 @@ import ( "github.com/ossf/criticality_score/cmd/enumerate_github/pagination" "github.com/shurcooL/githubv4" + log "github.com/sirupsen/logrus" ) // repo is part of the GitHub GraphQL query and includes the fields @@ -71,7 +72,9 @@ func buildQuery(q string, minStars, maxStars int) string { } func (re *Searcher) runRepoQuery(q string) (*pagination.Cursor, error) { - re.logger.V(1).Info("Searching GitHub", "query", q) + re.logger.WithFields(log.Fields{ + "query": q, + }).Debug("Searching GitHub") vars := map[string]interface{}{ "query": githubv4.String(q), "perPage": githubv4.Int(re.perPage), @@ -121,15 +124,14 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, em } } remaining := total - seen - re.logger.V(1).Info( - "Finished iterating through results", - "total_available", total, - "total_returned", seen, - "total_remaining", remaining, - "unique_repos", len(repos), - "last_stars", stars, - "query", q, - ) + re.logger.WithFields(log.Fields{ + "total_available": total, + "total_returned": seen, + "total_remaining": remaining, + "unique_repos": len(repos), + "last_stars": stars, + "query": q, + }).Debug("Finished iterating through results") newMaxStars := stars + overlap if remaining <= 0 { break @@ -138,14 +140,13 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, em } else { // the gap between "stars" and "maxStars" is less than "overlap", so we can't // safely step any lower without skipping stars. - re.logger.Error( - ErrorUnableToListAllResult, - "Too many repositories for current range", - "min_stars", minStars, - "stars", stars, - "max_stars", maxStars, - "overlap", overlap, - ) + re.logger.WithFields(log.Fields{ + "error": ErrorUnableToListAllResult, + "min_stars": minStars, + "stars": stars, + "max_stars": maxStars, + "overlap": overlap, + }).Error("Too many repositories for current range") return ErrorUnableToListAllResult } } diff --git a/cmd/enumerate_github/githubsearch/search.go b/cmd/enumerate_github/githubsearch/search.go index 5d5be001..b693294a 100644 --- a/cmd/enumerate_github/githubsearch/search.go +++ b/cmd/enumerate_github/githubsearch/search.go @@ -4,8 +4,8 @@ import ( "context" "errors" - "github.com/go-logr/logr" "github.com/shurcooL/githubv4" + log "github.com/sirupsen/logrus" ) // empty is a convenience wrapper for the empty struct. @@ -16,7 +16,7 @@ var ErrorUnableToListAllResult = errors.New("unable to list all results") type Searcher struct { ctx context.Context client *githubv4.Client - logger logr.Logger + logger *log.Entry perPage int } @@ -29,7 +29,7 @@ func PerPage(perPage int) Option { return option(func(s *Searcher) { s.perPage = perPage }) } -func NewSearcher(ctx context.Context, client *githubv4.Client, logger logr.Logger, options ...Option) *Searcher { +func NewSearcher(ctx context.Context, client *githubv4.Client, logger *log.Entry, options ...Option) *Searcher { s := &Searcher{ ctx: ctx, client: client, diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 0f32c862..ed25e362 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -11,17 +11,18 @@ import ( "sync" "time" - "github.com/go-logr/logr" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" - "github.com/ossf/scorecard/v4/log" + sclog "github.com/ossf/scorecard/v4/log" "github.com/shurcooL/githubv4" + log "github.com/sirupsen/logrus" ) const ( githubDateFormat = "2006-01-02" reposPerPage = 100 oneDay = time.Hour * 24 + defaultLogLevel = log.InfoLevel ) var ( @@ -37,7 +38,7 @@ var ( workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") startDateFlag = dateFlag(epochDate) endDateFlag = dateFlag(time.Now().UTC().Truncate(oneDay)) - logFlag = logLevelFlag(log.DefaultLevel) + logFlag = logLevelFlag(defaultLogLevel) ) // dateFlag implements the flag.Value interface to simplify the input and validation of @@ -66,12 +67,16 @@ func (d *dateFlag) Time() time.Time { type logLevelFlag log.Level func (l *logLevelFlag) Set(value string) error { - *l = logLevelFlag(log.ParseLevel(value)) + level, err := log.ParseLevel(string(value)) + if err != nil { + return err + } + *l = logLevelFlag(level) return nil } func (l logLevelFlag) String() string { - return string(log.Level(l)) + return log.Level(l).String() } func (l logLevelFlag) Level() log.Level { @@ -97,7 +102,7 @@ func init() { // and returns each repository on the results channel. // // When the queries channel is closed it will call wg.Done() to signal that the worker has finished. -func searchWorker(s *githubsearch.Searcher, wg *sync.WaitGroup, logger logr.Logger, queries, results chan string) { +func searchWorker(s *githubsearch.Searcher, wg *sync.WaitGroup, logger *log.Entry, queries, results chan string) { defer wg.Done() for q := range queries { total := 0 @@ -107,7 +112,10 @@ func searchWorker(s *githubsearch.Searcher, wg *sync.WaitGroup, logger logr.Logg }) if err != nil { // TODO: this error handling is not at all graceful, and hard to recover from. - logger.Error(err, "Enumeration failed for query", "query", q) + logger.WithFields(log.Fields{ + "query": q, + "error": err, + }).Error("Enumeration failed for query") if errors.Is(err, githubsearch.ErrorUnableToListAllResult) { if *requireMinStarsFlag { os.Exit(1) @@ -116,42 +124,47 @@ func searchWorker(s *githubsearch.Searcher, wg *sync.WaitGroup, logger logr.Logg os.Exit(1) } } - logger.Info("Enumeration for query done", "query", q, "repo_count", total) + logger.WithFields(log.Fields{ + "query": q, + "repo_count": total, + }).Info("Enumeration for query done") } } func main() { flag.Parse() + logger := log.New() + logger.SetLevel(logFlag.Level()) + // roundtripper requires us to use the scorecard logger. - // TODO: try and replace this with logrus directly. - logger := log.NewLogger(logFlag.Level()) + scLogger := sclog.NewLogrusLogger(logger) // Ensure the -start date is not before the epoch. if startDateFlag.Time().Before(epochDate) { - logger.Error(nil, fmt.Sprintf("-start date must be no earlier than %s", epochDate.Format(githubDateFormat))) + logger.Errorf("-start date must be no earlier than %s", epochDate.Format(githubDateFormat)) os.Exit(2) } // Ensure -start is before -end if endDateFlag.Time().Before(startDateFlag.Time()) { - logger.Error(nil, "-start date must be before -end date") + logger.Error("-start date must be before -end date") os.Exit(2) } // Ensure a non-flag argument (the output file) is specified. if flag.NArg() != 1 { - logger.Error(nil, "An output file must be specified.") + logger.Error("An output file must be specified.") os.Exit(2) } outFilename := flag.Arg(0) // Print a helpful message indicating the configuration we're using. - logger.Info( - "Preparing output file", - "filename", outFilename, - "force", *forceFlag, - "append", *appendFlag) + logger.WithFields(log.Fields{ + "filename": outFilename, + "force": *forceFlag, + "append": *appendFlag, + }).Info("Preparing output file") // Open the output file based on the flags // TODO: support '-' to use os.Stdout. @@ -165,26 +178,28 @@ func main() { out, err = os.OpenFile(outFilename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|os.O_EXCL, 0666) } if err != nil { - // file failed to open - panic(err) + // File failed to open + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to open output file") + os.Exit(2) } defer out.Close() - logger.Info( - "Starting enumeration", - "start", startDateFlag.String(), - "end", endDateFlag.String(), - "min_stars", *minStarsFlag, - "star_overlap", *starOverlapFlag, - "workers", *workersFlag, - ) + logger.WithFields(log.Fields{ + "start": startDateFlag.String(), + "end": endDateFlag.String(), + "min_stars": *minStarsFlag, + "star_overlap": *starOverlapFlag, + "workers": *workersFlag, + }).Info("Starting enumeration") // Track how long it takes to enumerate the repositories startTime := time.Now() ctx := context.Background() // Prepare a client for communicating with GitHub's GraphQL API - rt := roundtripper.NewTransport(ctx, logger) + rt := roundtripper.NewTransport(ctx, scLogger) httpClient := &http.Client{ Transport: rt, } @@ -198,7 +213,7 @@ func main() { // Start the worker goroutines to execute the search queries for i := 0; i < *workersFlag; i++ { - workerLogger := logger.WithValues("worker", i) + workerLogger := logger.WithFields(log.Fields{"worker": i}) s := githubsearch.NewSearcher(ctx, client, workerLogger, githubsearch.PerPage(reposPerPage)) go searchWorker(s, &wg, workerLogger, queries, results) } @@ -216,23 +231,25 @@ func main() { // Work happens here. Iterate through the dates from today, until the start date. for created := endDateFlag.Time(); !startDateFlag.Time().After(created); created = created.Add(-oneDay) { - logger.Info("Scheduling day for enumeration", "created", created.Format(githubDateFormat)) + logger.WithFields(log.Fields{ + "created": created.Format(githubDateFormat), + }).Info("Scheduling day for enumeration") queries <- baseQuery + fmt.Sprintf(" created:%s", created.Format(githubDateFormat)) } - logger.V(1).Info("Waiting for workers to finish") + logger.Debug("Waiting for workers to finish") // Indicate to the workers that we're finished. close(queries) // Wait for the workers to be finished. wg.Wait() - logger.V(1).Info("Waiting for writer to finish") + logger.Debug("Waiting for writer to finish") // Close the results channel now the workers are done. close(results) // Wait for the writer to be finished. <-done - logger.Info( - "Finished enumeration", - "total_repos", totalRepos, - "duration", time.Now().Sub(startTime).Truncate(time.Minute).String()) + logger.WithFields(log.Fields{ + "total_repos": totalRepos, + "duration": time.Now().Sub(startTime).Truncate(time.Minute).String(), + }).Info("Finished enumeration") } diff --git a/go.mod b/go.mod index 239796fc..08cab178 100644 --- a/go.mod +++ b/go.mod @@ -3,40 +3,23 @@ module github.com/ossf/criticality_score go 1.18 require ( - github.com/go-logr/logr v1.2.2 + github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 + github.com/sirupsen/logrus v1.8.1 ) require ( - cloud.google.com/go v0.100.2 // indirect - cloud.google.com/go/compute v0.1.0 // indirect - cloud.google.com/go/iam v0.1.1 // indirect - cloud.google.com/go/storage v1.18.2 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect - github.com/golang-jwt/jwt/v4 v4.0.0 // indirect + github.com/go-logr/logr v1.2.3 // indirect + github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.7 // indirect - github.com/google/go-github/v38 v38.1.0 // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect - github.com/google/wire v0.5.0 // indirect - github.com/googleapis/gax-go/v2 v2.1.1 // indirect - github.com/ossf/scorecard/v4 v4.1.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect - github.com/sirupsen/logrus v1.8.1 // indirect + github.com/stretchr/testify v1.7.1 // indirect go.opencensus.io v0.23.0 // indirect - gocloud.dev v0.24.0 // indirect - golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 // indirect - golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect - golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect - golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect - google.golang.org/api v0.67.0 // indirect - google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00 // indirect - google.golang.org/grpc v1.44.0 // indirect - google.golang.org/protobuf v1.27.1 // indirect + golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect + golang.org/x/net v0.0.0-20220401154927-543a649e0bdd // indirect + golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect ) diff --git a/go.sum b/go.sum index b1ad137d..3a0ca563 100644 --- a/go.sum +++ b/go.sum @@ -1,776 +1,139 @@ -bazil.org/fuse v0.0.0-20180421153158-65cc252bf669/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= -cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= -cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= -cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= -cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= -cloud.google.com/go v0.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= -cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= -cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= -cloud.google.com/go v0.88.0/go.mod h1:dnKwfYbP9hQhefiUvpbcAyoGSHUrOxR20JVElLiUvEY= -cloud.google.com/go v0.89.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= -cloud.google.com/go v0.92.2/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.92.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= -cloud.google.com/go v0.94.0/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= -cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= -cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= -cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= -cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v0.1.0 h1:rSUBvAyVwNJ5uQCKNJFMwPtTvJkfN38b6Pvb9zZoqJ8= -cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.5.0/go.mod h1:c4nNYR1qdq7eaZ+jSc5fonrQN2k3M7sWATcYTiakjEo= -cloud.google.com/go/iam v0.1.1 h1:4CapQyNFjiksks1/x7jsvsygFPhihslYk5GptIrlX68= -cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= -cloud.google.com/go/kms v0.1.0/go.mod h1:8Qp8PCAypHg4FdmlyW1QRAv09BGQ9Uzh7JnmIZxPk+c= -cloud.google.com/go/monitoring v0.1.0/go.mod h1:Hpm3XfzJv+UTiXzCG5Ffp0wijzHTC7Cv4eR7o3x/fEE= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.16.0/go.mod h1:6A8EfoWZ/lUvCWStKGwAWauJZSiuV0Mkmu6WilK/TxQ= -cloud.google.com/go/secretmanager v0.1.0/go.mod h1:3nGKHvnzDUVit7U0S9KAKJ4aOsO1xtwRG+7ey5LK1bM= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.16.1/go.mod h1:LaNorbty3ehnU3rEjXSNV/NRgQA0O8Y+uh6bPe5UOk4= -cloud.google.com/go/storage v1.18.2 h1:5NQw6tOn3eMm0oE8vTkfjau18kjL79FlMjy/CHTpmoY= -cloud.google.com/go/storage v1.18.2/go.mod h1:AiIj7BWXyhO5gGVmYJ+S8tbkCx3yb0IMjua8Aw4naVM= -cloud.google.com/go/trace v0.1.0/go.mod h1:wxEwsoeRVPbeSkt7ZC9nWCgmoKQRAoySN7XHW2AmI7g= -contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= -contrib.go.opencensus.io/exporter/stackdriver v0.13.8/go.mod h1:huNtlWx75MwO7qMs0KrMxPZXzNNWebav1Sq/pm02JdQ= -contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-amqp-common-go/v3 v3.1.0/go.mod h1:PBIGdzcO1teYoufTKMcGibdKaYZv4avS+O6LNIp8bq0= -github.com/Azure/azure-amqp-common-go/v3 v3.1.1/go.mod h1:YsDaPfaO9Ub2XeSKdIy2DfwuiQlHQCauHJwSqtrkECI= -github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= -github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v57.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-service-bus-go v0.10.16/go.mod h1:MlkLwGGf1ewcx5jZadn0gUEty+tTg0RaElr6bPf+QhI= -github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= -github.com/Azure/go-amqp v0.13.0/go.mod h1:qj+o8xPCz9tMSbQ83Vp8boHahuRDl5mkNHyt1xlxUTs= -github.com/Azure/go-amqp v0.13.11/go.mod h1:D5ZrjQqB1dyp1A+G73xeL/kNn7D5qHJIIsNNps7YNmk= -github.com/Azure/go-amqp v0.13.12/go.mod h1:D5ZrjQqB1dyp1A+G73xeL/kNn7D5qHJIIsNNps7YNmk= -github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.3/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= -github.com/Azure/go-autorest/autorest v0.11.17/go.mod h1:eipySxLmqSyC5s5k1CLupqet0PSENBEDP93LQ9a8QYw= -github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.20/go.mod h1:o3tqFY+QR40VOlk+pV4d77mORO64jOXSgEnPQgLK6JY= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= -github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= -github.com/Azure/go-autorest/autorest/adal v0.9.11/go.mod h1:nBKAnTomx8gDtl+3ZCJv2v0KACFHWTB2drffI1B68Pk= -github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.15/go.mod h1:tGMin8I49Yij6AQ+rvV+Xa/zwxYQB5hmsd6DkfAx2+A= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.8/go.mod h1:kxyKZTSfKh8OVFWPAgOgQ/frrJgeYQJPyR5fLFmXko4= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.3/go.mod h1:yAQ2b6eP/CmLPnmLvxtT1ALIY3OR1oFcCqVBi8vHiTc= -github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= -github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= -github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.24.0/go.mod h1:3tx938GhY4FC+E1KT/jNjDw7Z5qxAEtIiERJ2sXjnII= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.40.34/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q= -github.com/aws/aws-sdk-go-v2 v1.9.0/go.mod h1:cK/D0BBs0b/oWPIcX/Z/obahJK1TT7IPVjy53i/mX/4= -github.com/aws/aws-sdk-go-v2/config v1.7.0/go.mod h1:w9+nMZ7soXCe5nT46Ri354SNhXDQ6v+V5wqDjnZE+GY= -github.com/aws/aws-sdk-go-v2/credentials v1.4.0/go.mod h1:dgGR+Qq7Wjcd4AOAW5Rf5Tnv3+x7ed6kETXyS9WCuAY= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.5.0/go.mod h1:CpNzHK9VEFUCknu50kkB8z58AH2B5DvPP7ea1LHve/Y= -github.com/aws/aws-sdk-go-v2/internal/ini v1.2.2/go.mod h1:BQV0agm+JEhqR+2RT5e1XTFIDcAAV0eW6z2trp+iduw= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.3.0/go.mod h1:R1KK+vY8AfalhG1AOu5e35pOD2SdoPKQCFLTvnxiohk= -github.com/aws/aws-sdk-go-v2/service/kms v1.5.0/go.mod h1:w7JuP9Oq1IKMFQPkNe3V6s9rOssXzOVEMNEqK1L1bao= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.6.0/go.mod h1:B+7C5UKdVq1ylkI/A6O8wcurFtaux0R1njePNPtKwoA= -github.com/aws/aws-sdk-go-v2/service/ssm v1.10.0/go.mod h1:4dXS5YNqI3SNbetQ7X7vfsMlX6ZnboJA2dulBwJx7+g= -github.com/aws/aws-sdk-go-v2/service/sso v1.4.0/go.mod h1:+1fpWnL96DL23aXPpMGbsmKe8jLTEfbjuQoA4WS1VaA= -github.com/aws/aws-sdk-go-v2/service/sts v1.7.0/go.mod h1:0qcSMCyASQPN2sk/1KQLQ2Fh6yq8wm0HSDAimPhzCoM= -github.com/aws/smithy-go v1.8.0/go.mod h1:SObp3lf9smib00L/v3U2eAKG8FyQ7iLrJnQiAmR5n+E= -github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 h1:tXKVfhE7FcSkhkv0UwkLvPDeZ4kz6OXd0PKPlFqf81M= github.com/bradleyfalzon/ghinstallation/v2 v2.0.4/go.mod h1:B40qPqJxWE0jDZgOR1JmaMy+4AY1eBP+IByOvqyAKp0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= -github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= -github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= -github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU= -github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= -github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= -github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= -github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= -github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.2 h1:ahHml/yUpnlb96Rp8HCvtYVPY8ZYpxq3g7UYchIYwbs= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= -github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= -github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= -github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= -github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= -github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/golang-jwt/jwt/v4 v4.0.0 h1:RAqyYixv1p7uEnocuy8P1nru5wprCh/MH2BIlW5z5/o= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= +github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= -github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= -github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= -github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= -github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-github/v38 v38.1.0 h1:C6h1FkaITcBFK7gAmq4eFzt6gbhEhk7L5z6R3Uva+po= -github.com/google/go-github/v38 v38.1.0/go.mod h1:cStvrz/7nFr0FoENgG6GLbp53WaelXucT+BBz/3VKx4= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= -github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= -github.com/google/go-replayers/httpreplay v1.0.0/go.mod h1:LJhKoTwS5Wy5Ld/peq8dFFG5OfJyHEz7ft+DsTUv25M= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210715191844-86eeefc3e471/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= -github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= -github.com/googleapis/gax-go/v2 v2.1.1 h1:dp3bWCh+PPO1zjRRiCSczJav13sBvG4UhNyVTa1KqdU= -github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= -github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= -github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.5/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= -github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/ossf/scorecard/v4 v4.1.0 h1:azfb4TQhO79k4u8IK/r0h94OUjewYIpv7waUdqvabeE= -github.com/ossf/scorecard/v4 v4.1.0/go.mod h1:qC9nQPRqMB5Jc77d3Z2KPtjYQkW7o6FbTPTfo7LZOr4= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 h1:Db6m7J/xaItRxVbesKIXwngw+Tr1IERv/LCnRBzhHvk= +github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4/go.mod h1:PbooSR+65A6HA+eoJ7ICwek/muANHZsR08QV24tuiKA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 h1:82EIpiGB79OIPgSGa63Oj4Ipf+YAX1c6A9qjmEYoRXc= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= -github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= -go.opencensus.io v0.22.6/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= -go.uber.org/multierr v1.7.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= -go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= -gocloud.dev v0.24.0 h1:cNtHD07zQQiv02OiwwDyVMuHmR7iQt2RLkzoAgz7wBs= -gocloud.dev v0.24.0/go.mod h1:uA+als++iBX5ShuG4upQo/3Zoz49iIPlYUWHV5mM8w8= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190325154230-a5d413f7728c/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210817164053-32db794688a5 h1:HWj/xjIHfjYU5nVXpTM0s39J9CbLn7Cc5a7IC5rwsMQ= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= -golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd h1:O7DYs+zxREGLKzKoMQrtrEacpb0ZVXA5rIwylE2Xchk= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220401154927-543a649e0bdd h1:zYlwaUHTmxuf6H7hwO2dgwqozQmH7zf4x+/qql4oVWc= +golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210126194326-f9ce19ea3013/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210223095934-7937bea0104d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27 h1:XDXtA5hveEEV8JB2l7nhMTp3t3cHp9ZpwcdjqyEWLlo= -golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY= +golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= -golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= -google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= -google.golang.org/api v0.37.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= -google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= -google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= -google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= -google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= -google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= -google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= -google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= -google.golang.org/api v0.52.0/go.mod h1:Him/adpjt0sxtkWViy0b6xyKW/SD71CwdJ7HqJo7SrU= -google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= -google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= -google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= -google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= -google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= -google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= -google.golang.org/api v0.67.0 h1:lYaaLa+x3VVUhtosaK9xihwQ9H9KRa557REHwwZ2orM= -google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210126160654-44e461bb6506/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= -google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= -google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= -google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= -google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= -google.golang.org/genproto v0.0.0-20210721163202-f1cecdd8b78a/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210722135532-667f2b7c528f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= -google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= -google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210825212027-de86158e7fda/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= -google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211016002631-37fc39342514/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00 h1:zmf8Yq9j+IyTpps+paSkmHkSu5fJlRKy69LxRzc17Q0= -google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= -google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= -google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= -google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= -google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -779,32 +142,13 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= -google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From d948f49f3a0caae689679c8231bd44f12ed5c333 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 14 Apr 2022 14:24:19 +1000 Subject: [PATCH 051/172] Add gomod and github-actions to dependabot configuration. (#113) --- .github/dependabot.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 491deae0..28f34c2d 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -5,3 +5,12 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 +- package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + open-pull-requests-limit: 10 +- package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" From 3ccc8f78dc518dd62c1ea01aa1d5310cef419d29 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 14 Apr 2022 04:24:53 +0000 Subject: [PATCH 052/172] Bump actions/checkout from 2 to 3 Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 33ed4975..04525ce8 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v2 + uses: actions/checkout@v3 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL From 83d7917bf7bd2328500df7fd2f8735d6c7d746c0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 26 Apr 2022 00:52:58 +0000 Subject: [PATCH 053/172] Bump github/codeql-action from 1 to 2 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/v1...v2) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 33ed4975..74199a4d 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -39,7 +39,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@v1 + uses: github/codeql-action/init@v2 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -50,7 +50,7 @@ jobs: # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). # If this step fails, then you should remove it and run the build manually (see below) - name: Autobuild - uses: github/codeql-action/autobuild@v1 + uses: github/codeql-action/autobuild@v2 # ℹ️ Command-line programs to run using the OS shell. # 📚 https://git.io/JvXDl @@ -64,4 +64,4 @@ jobs: # make release - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 + uses: github/codeql-action/analyze@v2 From b5f3ceaeecb8a7cfb3040b76380a11bd4c0ad7bb Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 26 Apr 2022 14:09:24 +1000 Subject: [PATCH 054/172] Remove "Finished()" API in favor of the io.EOF error. (#116) This better handles the case where another page is left, but contains no nodes and makes it less ambiguous. --- cmd/enumerate_github/githubsearch/repos.go | 8 ++++++-- cmd/enumerate_github/pagination/pagination.go | 19 +++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/cmd/enumerate_github/githubsearch/repos.go b/cmd/enumerate_github/githubsearch/repos.go index 6632a4b5..7076378b 100644 --- a/cmd/enumerate_github/githubsearch/repos.go +++ b/cmd/enumerate_github/githubsearch/repos.go @@ -1,7 +1,9 @@ package githubsearch import ( + "errors" "fmt" + "io" "github.com/ossf/criticality_score/cmd/enumerate_github/pagination" "github.com/shurcooL/githubv4" @@ -110,9 +112,11 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, em total := c.Total() seen := 0 stars = 0 - for !c.Finished() { + for { obj, err := c.Next() - if err != nil { + if obj == nil && errors.Is(err, io.EOF) { + break + } else if err != nil { return err } repo := obj.(repo) diff --git a/cmd/enumerate_github/pagination/pagination.go b/cmd/enumerate_github/pagination/pagination.go index f98b15c8..eb6d402b 100644 --- a/cmd/enumerate_github/pagination/pagination.go +++ b/cmd/enumerate_github/pagination/pagination.go @@ -58,25 +58,24 @@ func (c *Cursor) isLastPage() bool { return !c.query.HasNextPage() } -func (c *Cursor) Finished() bool { - return c.atEndOfPage() && c.isLastPage() -} - func (c *Cursor) Total() int { return c.query.Total() } func (c *Cursor) Next() (interface{}, error) { - if c.Finished() { - // We've finished so return an EOF - return nil, io.EOF - } else if c.atEndOfPage() { - // We're at the end of the page, but not finished, so grab the next page. + if c.atEndOfPage() { + // There are no more nodes in this page, so we need another page. + if c.isLastPage() { + // There are no more pages, so return an EOF + return nil, io.EOF + } + // Grab the next page. if err := c.queryNextPage(); err != nil { return nil, err } - // Make sure we didn't get an empty result. if c.atEndOfPage() { + // Despite grabing a new page we have no results, + // so return an EOF. return nil, io.EOF } } From c8bd546a4f8bc8bcb329c7010d97628dd5cbb3ce Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 28 Apr 2022 08:02:59 +1000 Subject: [PATCH 055/172] Place code to be shared with signal collection into libraries. (#117) --- cmd/enumerate_github/main.go | 22 ++--- internal/logflag/level.go | 32 +++++++ internal/logflag/level_test.go | 78 ++++++++++++++++ internal/outfile/outfile.go | 86 ++++++++++++++++++ internal/outfile/outfile_test.go | 147 +++++++++++++++++++++++++++++++ 5 files changed, 349 insertions(+), 16 deletions(-) create mode 100644 internal/logflag/level.go create mode 100644 internal/logflag/level_test.go create mode 100644 internal/outfile/outfile.go create mode 100644 internal/outfile/outfile_test.go diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index ed25e362..56ebc6dd 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -12,6 +12,8 @@ import ( "time" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" + "github.com/ossf/criticality_score/internal/logflag" + "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" sclog "github.com/ossf/scorecard/v4/log" "github.com/shurcooL/githubv4" @@ -29,8 +31,6 @@ var ( // epochDate is the earliest date for which GitHub has data. epochDate = time.Date(2008, 1, 1, 0, 0, 0, 0, time.UTC) - forceFlag = flag.Bool("force", false, "overwrites FILE if it already exists and -append is not set.") - appendFlag = flag.Bool("append", false, "appends to FILE if it already exists.") minStarsFlag = flag.Int("min-stars", 10, "only enumerates repositories with this or more of stars.") starOverlapFlag = flag.Int("star-overlap", 5, "the number of stars to overlap between queries.") requireMinStarsFlag = flag.Bool("require-min-stars", false, "abort if -min-stars can't be reached during enumeration.") @@ -38,7 +38,7 @@ var ( workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") startDateFlag = dateFlag(epochDate) endDateFlag = dateFlag(time.Now().UTC().Truncate(oneDay)) - logFlag = logLevelFlag(defaultLogLevel) + logFlag = logflag.Level(defaultLogLevel) ) // dateFlag implements the flag.Value interface to simplify the input and validation of @@ -87,6 +87,7 @@ func init() { flag.Var(&startDateFlag, "start", "the start `date` to enumerate back to. Must be at or after 2008-01-01.") flag.Var(&endDateFlag, "end", "the end `date` to enumerate from.") flag.Var(&logFlag, "log", "set the `level` of logging.") + outfile.DefineFlags(flag.CommandLine, "force", "append", "FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) w := flag.CommandLine.Output() @@ -162,21 +163,10 @@ func main() { // Print a helpful message indicating the configuration we're using. logger.WithFields(log.Fields{ "filename": outFilename, - "force": *forceFlag, - "append": *appendFlag, }).Info("Preparing output file") - // Open the output file based on the flags - // TODO: support '-' to use os.Stdout. - var out *os.File - var err error - if *appendFlag { - out, err = os.OpenFile(outFilename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|os.O_APPEND, 0666) - } else if *forceFlag { - out, err = os.OpenFile(outFilename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|os.O_TRUNC, 0666) - } else { - out, err = os.OpenFile(outFilename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|os.O_EXCL, 0666) - } + // Open the output file + out, err := outfile.Open(outFilename) if err != nil { // File failed to open logger.WithFields(log.Fields{ diff --git a/internal/logflag/level.go b/internal/logflag/level.go new file mode 100644 index 00000000..7014e69e --- /dev/null +++ b/internal/logflag/level.go @@ -0,0 +1,32 @@ +// Package logflag is a simple helper library that generalizes the logic for +// parsing command line flags for configuring the logging behavior. +package logflag + +import log "github.com/sirupsen/logrus" + +// Level implements the flag.Value interface to simplify the input and validation +// of the current logrus log level. +// +// var logLevel = logflag.Level(logrus.InfoLevel) +// flag.Var(&logLevel, "log", "set the `level` of logging.") +type Level log.Level + +// Set implements the flag.Value interface. +func (l *Level) Set(value string) error { + level, err := log.ParseLevel(string(value)) + if err != nil { + return err + } + *l = Level(level) + return nil +} + +// String implements the flag.Value interface. +func (l Level) String() string { + return log.Level(l).String() +} + +// Level returns either the default log level, or the value set on the command line. +func (l Level) Level() log.Level { + return log.Level(l) +} diff --git a/internal/logflag/level_test.go b/internal/logflag/level_test.go new file mode 100644 index 00000000..73f2605b --- /dev/null +++ b/internal/logflag/level_test.go @@ -0,0 +1,78 @@ +package logflag_test + +import ( + "flag" + "testing" + + "github.com/ossf/criticality_score/internal/logflag" + "github.com/sirupsen/logrus" +) + +func TestDefault(t *testing.T) { + level := logflag.Level(logrus.ErrorLevel) + if l := level.Level(); l != logrus.ErrorLevel { + t.Fatalf("Level() == %v, want %v", l, logrus.ErrorLevel) + } +} + +func TestSet(t *testing.T) { + level := logflag.Level(logrus.InfoLevel) + err := level.Set("error") + if err != nil { + t.Fatalf("Set() == %v, want nil", err) + } + if l := level.Level(); l != logrus.ErrorLevel { + t.Fatalf("Level() == %v, want %v", l, logrus.ErrorLevel) + } +} + +func TestSetError(t *testing.T) { + level := logflag.Level(logrus.InfoLevel) + err := level.Set("hello,world") + if err == nil { + t.Fatalf("Set() == nil, want an error") + } +} + +func TestString(t *testing.T) { + level := logflag.Level(logrus.DebugLevel) + if s := level.String(); s != logrus.DebugLevel.String() { + t.Fatalf("String() == %v, want %v", s, logrus.DebugLevel.String()) + } +} + +func TestFlagUnset(t *testing.T) { + fs := flag.NewFlagSet("", flag.ContinueOnError) + level := logflag.Level(logrus.InfoLevel) + fs.Var(&level, "level", "usage") + err := fs.Parse([]string{"arg"}) + if err != nil { + t.Fatalf("Parse() == %v, want nil", err) + } + if l := level.Level(); l != logrus.InfoLevel { + t.Fatalf("Level() == %v, want %v", l, logrus.InfoLevel) + } +} + +func TestFlagSet(t *testing.T) { + fs := flag.NewFlagSet("", flag.ContinueOnError) + level := logflag.Level(logrus.InfoLevel) + fs.Var(&level, "level", "usage") + err := fs.Parse([]string{"-level=fatal", "arg"}) + if err != nil { + t.Fatalf("Parse() == %v, want nil", err) + } + if l := level.Level(); l != logrus.FatalLevel { + t.Fatalf("Level() == %v, want %v", l, logrus.FatalLevel) + } +} + +func TestFlagSetError(t *testing.T) { + fs := flag.NewFlagSet("", flag.ContinueOnError) + level := logflag.Level(logrus.InfoLevel) + fs.Var(&level, "level", "usage") + err := fs.Parse([]string{"-level=foobar", "arg"}) + if err == nil { + t.Fatalf("Parse() == nil, want an error") + } +} diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go new file mode 100644 index 00000000..a4be6bc3 --- /dev/null +++ b/internal/outfile/outfile.go @@ -0,0 +1,86 @@ +package outfile + +import ( + "flag" + "fmt" + "os" +) + +// fileOpener wraps a method for opening files. +// +// This allows tests to fake the behavior of os.OpenFile() to avoid hitting +// the filesystem. +type fileOpener interface { + Open(string, int, os.FileMode) (*os.File, error) +} + +// fileOpenerFunc allows a function to implement the openFileWrapper interface. +// +// This is convenient for wrapping os.OpenFile(). +type fileOpenerFunc func(string, int, os.FileMode) (*os.File, error) + +func (f fileOpenerFunc) Open(filename string, flags int, perm os.FileMode) (*os.File, error) { + return f(filename, flags, perm) +} + +type Opener struct { + force bool + append bool + fileOpener fileOpener + Perm os.FileMode + StdoutName string +} + +// CreateOpener creates an Opener and defines the sepecified flags forceFlag and appendFlag. +func CreateOpener(fs *flag.FlagSet, forceFlag string, appendFlag string, fileHelpName string) *Opener { + o := &Opener{ + Perm: 0666, + StdoutName: "-", + fileOpener: fileOpenerFunc(os.OpenFile), + } + fs.BoolVar(&(o.force), forceFlag, false, fmt.Sprintf("overwrites %s if it already exists and -%s is not set.", fileHelpName, appendFlag)) + fs.BoolVar(&(o.append), appendFlag, false, fmt.Sprintf("appends to %s if it already exists.", fileHelpName)) + return o +} + +func (o *Opener) openInternal(filename string, extraFlags int) (*os.File, error) { + return o.fileOpener.Open(filename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|extraFlags, o.Perm) +} + +// Open opens and returns a file for output with the given filename. +// +// If filename is equal to o.StdoutName, os.Stdout will be used. +// If filename does not exist, it will be created with the mode set in o.Perm. +// If filename does exist, the behavior of this function will depend on the +// flags: +// - if appendFlag is set on the command line the existing file will be +// appended to. +// - if forceFlag is set on the command line the existing file will be +// truncated. +// - if neither forceFlag nor appendFlag are set an error will be +// returned. +func (o *Opener) Open(filename string) (f *os.File, err error) { + if o.StdoutName != "" && filename == o.StdoutName { + f = os.Stdout + } else if o.append { + f, err = o.openInternal(filename, os.O_APPEND) + } else if o.force { + f, err = o.openInternal(filename, os.O_TRUNC) + } else { + f, err = o.openInternal(filename, os.O_EXCL) + } + return +} + +var defaultOpener *Opener + +// DefineFlags is a wrapper around CreateOpener for updating a default instance +// of Opener. +func DefineFlags(fs *flag.FlagSet, forceFlag string, appendFlag string, fileHelpName string) { + defaultOpener = CreateOpener(fs, forceFlag, appendFlag, fileHelpName) +} + +// Open is a wrapper around Opener.Open for the default instance of Opener. +func Open(filename string) (*os.File, error) { + return defaultOpener.Open(filename) +} diff --git a/internal/outfile/outfile_test.go b/internal/outfile/outfile_test.go new file mode 100644 index 00000000..f91f4382 --- /dev/null +++ b/internal/outfile/outfile_test.go @@ -0,0 +1,147 @@ +package outfile + +import ( + "errors" + "flag" + "os" + "testing" +) + +type openCall struct { + filename string + flags int + perm os.FileMode +} + +type testOpener struct { + flag *flag.FlagSet + openErr error + lastOpen *openCall + opener *Opener +} + +func newTestOpener() *testOpener { + o := &testOpener{} + o.flag = flag.NewFlagSet("", flag.ContinueOnError) + o.opener = CreateOpener(o.flag, "force", "append", "FILE") + o.opener.Perm = 0567 + o.opener.StdoutName = "-stdout-" + o.opener.fileOpener = fileOpenerFunc(func(filename string, flags int, perm os.FileMode) (*os.File, error) { + o.lastOpen = &openCall{ + filename: filename, + flags: flags, + perm: perm, + } + if o.openErr != nil { + return nil, o.openErr + } else { + return &os.File{}, nil + } + }) + return o +} + +func TestForceFlagDefined(t *testing.T) { + o := newTestOpener() + f := o.flag.Lookup("force") + if f == nil { + t.Fatal("Lookup() == nil, wanted a flag.") + } +} + +func TestAppendFlagDefined(t *testing.T) { + o := newTestOpener() + f := o.flag.Lookup("append") + if f == nil { + t.Fatal("Lookup() == nil, wanted a flag.") + } +} + +func TestOpenStdout(t *testing.T) { + o := newTestOpener() + f, err := o.opener.Open("-stdout-") + if err != nil { + t.Fatalf("Open() == %v, want nil", err) + } + if f != os.Stdout { + n := "nil" + if f != nil { + n = f.Name() + } + t.Fatalf("Open() == %s, want %v", n, os.Stdout.Name()) + } +} + +func TestOpenFlagTest(t *testing.T) { + tests := []struct { + name string + args []string + openErr error + expectedFlag int + }{ + { + name: "no args", + args: []string{}, + expectedFlag: os.O_EXCL, + }, + { + name: "append only flag", + args: []string{"-append"}, + expectedFlag: os.O_APPEND, + }, + { + name: "force only flag", + args: []string{"-force"}, + expectedFlag: os.O_TRUNC, + }, + { + name: "both flags", + args: []string{"-force", "-append"}, + expectedFlag: os.O_APPEND, + }, + } + + // Test success responses + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + o := newTestOpener() + o.flag.Parse(test.args) + f, err := o.opener.Open("path/to/file") + if err != nil { + t.Fatalf("Open() == %v, want nil", err) + } + if f == nil { + t.Fatal("Open() == nil, want a file") + } + assertLastOpen(t, o, "path/to/file", test.expectedFlag, 0567) + }) + } + + // Test error responses + for _, test := range tests { + t.Run(test.name+" error", func(t *testing.T) { + o := newTestOpener() + o.flag.Parse(test.args) + o.openErr = errors.New("test error") + _, err := o.opener.Open("path/to/file") + if err == nil { + t.Fatalf("Open() is nil, want %v", o.openErr) + } + }) + } +} + +func assertLastOpen(t *testing.T, o *testOpener, filename string, requireFlags int, perm os.FileMode) { + if o.lastOpen == nil { + t.Fatalf("Open(...) not called, want call to Open(...)") + } + if o.lastOpen.filename != filename { + t.Fatalf("Open(%v, _, _) called, want Open(%v, _, _)", o.lastOpen.filename, filename) + } + if o.lastOpen.flags&requireFlags != requireFlags { + t.Fatalf("Open(_, %v, _) called, want Open(_, %v, _)", o.lastOpen.flags&requireFlags, requireFlags) + } + if o.lastOpen.perm != perm { + t.Fatalf("Open(_, _, %v) called, want Open(_, _, %v)", o.lastOpen.perm, perm) + } +} From 352a60f3c8a02df437ba52b7564638a7dcc99192 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 2 May 2022 11:42:18 +1000 Subject: [PATCH 056/172] Add a milestone 1 doc. (#118) This doc describes work towards solving #108 --- docs/design/milestone_1.md | 330 +++++++++++++++++++++++++++++++++++++ docs/glossary.md | 88 ++++++++++ 2 files changed, 418 insertions(+) create mode 100644 docs/design/milestone_1.md create mode 100644 docs/glossary.md diff --git a/docs/design/milestone_1.md b/docs/design/milestone_1.md new file mode 100644 index 00000000..84efb83d --- /dev/null +++ b/docs/design/milestone_1.md @@ -0,0 +1,330 @@ + +# Criticality Score Revamp: Milestone 1 + +- Author: [calebbrown@google.com](mailto:calebbrown@google.com) +- Updated: 2022-04-29 + +## Goal + +Anyone can reliably generate the existing set of signal data using the +`criticality_score` GitHub project, and calculate the scores using the +existing algorithm. + +Additionally there will be a focus on supporting future moves towards scaling +and automating criticality score. + +For this milestone, collecting dependent signal data sourced from +[deps.dev](https://deps.dev) will also be added to improve the overall +quality of the score produced. + +### Non-goals + +**Improve how the score is calculated.** + +While this is overall vital, the ability to calculate the score depends on +having reliable signals to base the score on. + +**Cover source repositories hosted on non-GitHub hosts.** + +Critical projects are hosted on GitLab, Bitbucket, or even self-hosted. These +should be supported, but given that over 90% of open source projects are +hosted by GitHub it seems prudent to focus efforts there first. + +**De-dupe mirrors from origin source repositories.** + +Mirrors are frequently used to provide broader access to a project. Usually +when a self-hosted project uses a public service, such as GitHub, to host a +mirror of the project. + +This milestone will not attempt to detect and canonicalize mirrors. + +## Background + +The OpenSSF has a +[Working Group (WG) focused on Securing Critical Projects](https://github.com/ossf/wg-securing-critical-projects). +A key part of this WG is focused on determining which Open Source projects are +"critical". Critical Open Source projects are those which are broadly depended +on by organizations, and present a security risk to those organizations, and +their customers, if they are not supported. + +This project is one of a small set of sources of data used to find theses +critical projects. + +The current Python implementation available in this repo has been stagnant for +a while. + +It has some serious problems with how it enumerates projects on GitHub (see +[#33](https://github.com/ossf/criticality_score/issues/33)), and lacks robust +support for non-GitHub projects (see +[#29](https://github.com/ossf/criticality_score/issues/29)). + +There are problems with the existing signals being collected (see +[#55](https://github.com/ossf/criticality_score/issues/55), +[#102](https://github.com/ossf/criticality_score/issues/102)) and interest in +exploring other signals and approaches +([#53](https://github.com/ossf/criticality_score/issues/53), +[#102](https://github.com/ossf/criticality_score/issues/102) deps.dev, +[#31](https://github.com/ossf/criticality_score/issues/31), +[#82](https://github.com/ossf/criticality_score/issues/82), etc). + +Additionally, in [#102](https://github.com/ossf/criticality_score/issues/102) I propose an approach to improving the quality of the criticality score. + +## Design Overview + +This milestone is a fundamental rearchitecturing of the project to meet the +goals of higher reliability, extensibility and ease of use. + +The design focuses on: + +- reliable GitHub project enumeration. +- reliable signal collection, with better dependent data. +- being able to update the criticality scores and rankings more frequently. + +Please see the [glossary](../glossary.md) for a terms used in this project. + +### Multi Stage + +The design takes a multi stage approach to generating raw criticality signal +data ready for ingestion into a BigQuery table. + +The stages are: + +* **Project enumeration** - produce a list of project repositories, focusing + initially on GitHub for Milestone 1. +* **Raw signal collection** - iterate through the list of projects and query + various data sources for raw signals. +* **BigQuery ingestion** - take the raw signals and import them into a BigQuery + table for querying and scoring. + +Some API efficiency is gained by collecting some raw signals during project +enumeration. However, the ability to run stages separately and at different +frequencies improves the overall reliability of the project, and allows for raw +signal data to be refreshed more frequently. + +## Detailed Design + +### Project enumeration + +#### Direct GitHub Enumeration + +##### Challenges + +* GitHub has a lot of repos. Over 2.5M repos with 5 or more stars, and over + 400k repos with 50 or more stars at the time of writing. +* GitHub's API only allows you to iterate through 1000 results. +* GitHub's API has limited methods of sorting and filtering. + +Given these limitations it is difficult to extract all the repositories over +a certain number of stars, as the number of repositories with low stars exceeds +the 1000 result limit of GitHub's API. + +The lowest number of stars that returns fewer than 1000 results can be improved +by stepping through each creation date. + +With a sufficiently high minimum star threshold (e.g. 20), most creation dates +will have fewer than 1000 results in total. + +##### Algorithm + +* Set `MIN_STARS` to a value chosen such that the number of repositories with + that number of stars is less than 1000 for any given creation date. +* Set `STAR_OVERLAP`, `START_DATE` and `END_DATE` +* For each `DATE` between `START_DATE` and `END_DATE`: + * Set `MAX_STARS` to infinity + * Search for repos with a creation date of `DATE` and stars between + `MAX_STARS` and `MIN_STARS` inclusive, ordered from highest stars to + lowest. + * While True: + * For each repository (GitHub limits this to 1000 results): + * If the repository has not been seen: + * Add it to the list of repositories + * If there were fewer than 1000 results: + * Break + * Set `MAX_STARS` to the the number of stars the last repository + returned + `STAR_OVERLAP` + * If `MAX_STARS` is the same as the previous value + * Break + +The current implementation of this algorithm has a difference between GitHub +search of less than 0.05% for >=20 stars (GitHub search was checked ~12 hours +after the algorithm finished) and took 4 hours with 1 worker and 1 token. + +##### Rate Limits + +A pool of GitHub tokens will be supported for increased performance. + +A single GitHub token has a limit of "5000" each hour, a single search page +consumes "1", and returning the 1000 results from a search consumes "10". This +allows 500 search queries per hour for a single token. + +##### Output + +Output from enumeration will be a text file containing a list of GitHub urls. + +#### Static Project URL Lists + +Rather than repeatedly query project repositories for a list of projects, use +pre-generated static lists of project repository URLs. + +Sources: + +* Prior invocations of the enumeration tool +* Manually curated lists of URLs +* [GHTorrent](https://ghtorrent.org/) data dumps + +##### GHTorrent + +GHTorrent monitors GitHub's public event feed and provides a fairly +comprehensive source of projects. + +Data from GHTorrent needs to be extracted from the SQL dump and filtered to +eliminate deleted repositories. + +The 2021-03-06 dump includes approx 190M repositories. This many repositories +would need to be curated to ensure each repository is still available. Culling +for "interesting" (e.g. more than 1 star) repositories may also be useful to +limit the amount of work generating signals. + +#### Future Sources of Projects + +There are many other sources of projects for future milestones that can be +used. These are out-of-scope for Milestone 1, but worth listing. + +* Other source repositories such as GitLab and Bitbucket. +* [https://deps.dev/](https://deps.dev/) projects. This source captures many + projects that exist in package repositories and helps connect projects to + their packages and dependents. +* GHTorrent or GH Archive - these can avoid the expense of querying GitHub's + API directly. +* Google dorking - use Google's advanced search capabilities to find + self-hosted repositories (e.g. cgit, gitea, etc) +* JIRA, Bugzilla, etc support for issue tracking + +### Raw Signal Collection + +This stage is when the list of projects are iterated over and for each project +a set of raw signal data is output. + +#### Input / Output + +Input: + +* One or more text files containing a list of project urls, one URL per line + +Output: + +* Either JSON or CSV formatted records for each project in UTF-8, including + the project url. The output will support direct loading into BigQuery. + +#### Signal Collectors + +Signal collection will be built around multiple signal _collectors_ that +produce one or more _signals_ per repository. + +Signal collectors fall into one of three categories: + +* Source repository and hosting signal collectors (e.g. GitHub, Bitbucket, + cGit) +* Issue tracking signal collectors (e.g. GitHub, Bugzilla, JIRA) +* Additional signal collectors (e.g deps.dev) + +Each repository can have only one set of signals from a source repository +collector and one set of signals from an issue tracking signal collector, but +can have signals from many additional collectors. + +#### Repository Object + +During the collection process a repository object will be created and passed to +each collector. + +As each part of the collection process runs, data will be fetched for a +repository. The repository object will serve as the interface for accessing +repository specific data so that it can be cached and limit the amount of +additional queries that need to be executed. + +#### Collection Process + +The general process for collecting signals will do the following: + +* Initialize all the collectors +* For each repository URL + * Gather basic data about the repository (e.g. stars, has it moved, urls) + * It may have been removed, in which case the repository can be + skipped. + * It may not be "interesting" (e.g. too few stars) and should be + skipped. + * It may have already been processed and should be skipped. + * Determine the set of collectors that apply to the repository. + * For each collector: + * Start collecting the signals for the current repository + * Wait for all collectors to complete + * Write the signals to the output. + +#### Signal Fields + +##### Naming + +Signal fields will fall under the general naming pattern of +`[collector].[name]`. + +Where `[collector]` and `[name]` are made up of one or more of the +following: + +* Lowercase characters +* Numbers +* Underscores. + +The following restrictions further apply to `[collector]` names: + +* Source repository signal collectors must use the `repo` collector name +* Issue tracking signal collectors must use the `issues` collector name +* Signals matching the original set in the Python implementation can also use + the `legacy` collector name +* Additional collectors can use any other valid name. + +Finally, `[name]` names must include the unit value if it is not implied by +the type, and any time constraints. + +* e.g. `last_update_days` +* e.g. `comment_count_prev_year` + +##### Types + +For Milestone 1, all signal fields will be scalars. More complex data types are +out of scope. + +Supported scalars can be: + +* Boolean +* Int +* Float +* String +* Date +* DateTime + +All Dates and DateTimes must be in UTC. + +Strings will support Unicode. + +#### Batching (out of scope) + +More efficient usage of GitHub's APIs can be achieved by batching together +related requests. Support for batching is considered out of scope for +Milestone 1. + +### BigQuery Ingestion + +Injection into BigQuery will be done for Milestone 1 using the `bq` command +line tool. + +### Language Choice + +The Scorecard project and Criticality Score share many of the same needs. + +Scorecards also interacts with the GitHub API, negotiates rate limiting and +handles pools of GitHub tokens. + +Therefore it makes sense to move towards these projects sharing code. + +As Scorecards is a more mature project, this requires Criticality Score to be +rewritten in Go. diff --git a/docs/glossary.md b/docs/glossary.md new file mode 100644 index 00000000..3532bc94 --- /dev/null +++ b/docs/glossary.md @@ -0,0 +1,88 @@ +# Glossary + +This document defines the meaning of various terms used by this project. +This is to ensure they are clearly understood. + +Please keep the document sorted alphabetically. + +## Terms + +### Fork + +A _fork_, like a mirror, is a clone or copy of another project's source code or +repository. + +A fork has two primary uses: + +* A contributor commiting changes to a fork for preparing pull-requests to the + main repository. +* A fork may become its own project when the original is unmaintained, or if + the forker decides to head in a different direction. + +Forks merely used for committing changes for a pull-request are not interesting +when calculating criticality scores. + +See also "Mirror". + +### Mirror + +A _mirror_, like a fork, is a clone or copy of another project's source code or +repository. + +A mirror is usually used to provide broader access to a repository, such as +when a self-hosted project mirrors its repository on GitHub. + +Mirrors may require de-duping to avoid treating the original repository and +its mirrors as separate projects. + +See also "Fork". + +### Project + +A _project_ is defined as only having a _single repository_, and a _single +issue tracker_. A project may provide multiple _packages_. + +There are some "umbrella projects" (e.g. Kubernetes) that have multiple +repositories associated with them, or may use a centralized issue tracker. An +alternative approach would be to treat a project independently of the one or +more repositories that belong to it. + +However this approach has the following drawbacks: + +* Makes it hard to distinguish between organizations and umbrella projects +* Raises the possibility that a part of the umbrella project that is critical + to OSS is missed. +* Complicates the calculation required to aggregate signals and generate a + criticality score. + +So instead we define a project as a single repository. This provides a clear +"primary key" we can use for collecting signals. + +### Repository + +A _repository_ refers to the system used to store and manage access to a +project's source code. Usually a version control system (e.g. git or mercurial) +is used to track and manage changes to the source code. + +A _repository_ can be the canonical source of a project's code, or it could +also be a _fork_ or a _mirror_. + +A _repository_ is usually owned by an individual or an organization, although +the specifics of how this behaves in practice depends on the repositories host. + +### Repository Host + +A _repository host_ is the service hosting a _repository_. It may be a service +such as GitHub, GitLab or Bitbucket. It may also be "self-hosted", where the +infrastructure for hosting a repository is managed by the maintainers of a +project. + +Self-hosted repositories often deploy an open-source application to provide +access, such as GitLab, cGit, or Gitea. + +### Umbrella Project + +An _umbrella project_ is a group of related projects that are maintained by a +larger community surrounding the project. + +See also "project". \ No newline at end of file From dcd72c8d9812c0ad2593b5f3c7a42bc311fc0cdd Mon Sep 17 00:00:00 2001 From: Abhishek Arya Date: Sat, 21 May 2022 07:15:58 -0700 Subject: [PATCH 057/172] Update milestone_1.md --- docs/design/milestone_1.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/milestone_1.md b/docs/design/milestone_1.md index 84efb83d..4b7aaef0 100644 --- a/docs/design/milestone_1.md +++ b/docs/design/milestone_1.md @@ -1,7 +1,7 @@ # Criticality Score Revamp: Milestone 1 -- Author: [calebbrown@google.com](mailto:calebbrown@google.com) +- Author: [Caleb Brown](mailto:calebbrown@google.com) - Updated: 2022-04-29 ## Goal From 678f3d3142b9087b6585367a19f9ff0a5c01c48f Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 27 May 2022 09:17:33 +1000 Subject: [PATCH 058/172] Initial commit of the collect_signals command. (#120) * Initial commit of the `collect_signals` command. - defines key APIs: - projectrepo.Repo and projectrepo.Factory - signal.Set and signal.Signal - collector.Collector and collector.Registry - implements the complete current set of signals for GitHub repos. - supports CSV output. - refactors GitHub API related code into an internal package for reuse. There is lots of work remaining: - unit testing / improving testability - improving the breakdown of legacy code and queries.go - docs, docs, docs. --- .gitignore | 3 + cmd/collect_signals/collector/collector.go | 25 ++ cmd/collect_signals/collector/registry.go | 135 ++++++++++ cmd/collect_signals/github/collector.go | 123 +++++++++ cmd/collect_signals/github/factory.go | 38 +++ .../github/legacy/constants.go | 23 ++ .../github/legacy/contributors.go | 108 ++++++++ cmd/collect_signals/github/legacy/created.go | 55 ++++ cmd/collect_signals/github/legacy/issues.go | 62 +++++ cmd/collect_signals/github/legacy/releases.go | 93 +++++++ cmd/collect_signals/github/legacy/util.go | 25 ++ cmd/collect_signals/github/queries.go | 76 ++++++ cmd/collect_signals/github/repo.go | 68 +++++ .../githubmentions/collector.go | 67 +++++ cmd/collect_signals/main.go | 191 ++++++++++++++ cmd/collect_signals/projectrepo/repo.go | 24 ++ cmd/collect_signals/result/csv.go | 96 +++++++ cmd/collect_signals/result/emitter.go | 27 ++ cmd/collect_signals/signal/issues.go | 11 + cmd/collect_signals/signal/repo.go | 26 ++ cmd/collect_signals/signal/signal.go | 241 ++++++++++++++++++ cmd/enumerate_github/githubsearch/repos.go | 14 +- docs/design/milestone_1.md | 10 +- go.mod | 2 + go.sum | 7 +- internal/githubapi/batch.go | 46 ++++ internal/githubapi/client.go | 30 +++ internal/githubapi/errors.go | 19 ++ .../githubapi}/pagination/pagination.go | 10 +- 29 files changed, 1639 insertions(+), 16 deletions(-) create mode 100644 cmd/collect_signals/collector/collector.go create mode 100644 cmd/collect_signals/collector/registry.go create mode 100644 cmd/collect_signals/github/collector.go create mode 100644 cmd/collect_signals/github/factory.go create mode 100644 cmd/collect_signals/github/legacy/constants.go create mode 100644 cmd/collect_signals/github/legacy/contributors.go create mode 100644 cmd/collect_signals/github/legacy/created.go create mode 100644 cmd/collect_signals/github/legacy/issues.go create mode 100644 cmd/collect_signals/github/legacy/releases.go create mode 100644 cmd/collect_signals/github/legacy/util.go create mode 100644 cmd/collect_signals/github/queries.go create mode 100644 cmd/collect_signals/github/repo.go create mode 100644 cmd/collect_signals/githubmentions/collector.go create mode 100644 cmd/collect_signals/main.go create mode 100644 cmd/collect_signals/projectrepo/repo.go create mode 100644 cmd/collect_signals/result/csv.go create mode 100644 cmd/collect_signals/result/emitter.go create mode 100644 cmd/collect_signals/signal/issues.go create mode 100644 cmd/collect_signals/signal/repo.go create mode 100644 cmd/collect_signals/signal/signal.go create mode 100644 internal/githubapi/batch.go create mode 100644 internal/githubapi/client.go create mode 100644 internal/githubapi/errors.go rename {cmd/enumerate_github => internal/githubapi}/pagination/pagination.go (88%) diff --git a/.gitignore b/.gitignore index 13727aa8..b83972c3 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ __pycache__/ # Rope project settings .ropeproject + +# Installing the package locally for development +*.egg-info \ No newline at end of file diff --git a/cmd/collect_signals/collector/collector.go b/cmd/collect_signals/collector/collector.go new file mode 100644 index 00000000..5bfb4f62 --- /dev/null +++ b/cmd/collect_signals/collector/collector.go @@ -0,0 +1,25 @@ +package collector + +import ( + "context" + + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" + "github.com/ossf/criticality_score/cmd/collect_signals/signal" +) + +// A Collector is used to collect a set of signals for a given +// project repository. +type Collector interface { + // EmptySet returns an empty instance of a signal Set that can be used for + // determining the namespace and signals supported by the Collector. + EmptySet() signal.Set + + // IsSupported returns true if the Collector supports the supplied Repo. + IsSupported(projectrepo.Repo) bool + + // Collect gathers and returns a Set of signals for the given project repo. + // + // An error is returned if it is unable to successfully gather the signals, + // or if the context is cancelled. + Collect(context.Context, projectrepo.Repo) (signal.Set, error) +} diff --git a/cmd/collect_signals/collector/registry.go b/cmd/collect_signals/collector/registry.go new file mode 100644 index 00000000..261a1d35 --- /dev/null +++ b/cmd/collect_signals/collector/registry.go @@ -0,0 +1,135 @@ +package collector + +import ( + "context" + "fmt" + + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" + "github.com/ossf/criticality_score/cmd/collect_signals/signal" +) + +// empty is a convenience wrapper for the empty struct. +type empty struct{} + +var globalRegistry = NewRegistry() + +type Registry struct { + cs []Collector +} + +// NewRegistry creates a new instance of Registry. +func NewRegistry() *Registry { + return &Registry{} +} + +// containsCollector returns true if c has already been registered. +func (r *Registry) containsCollector(c Collector) bool { + for _, regC := range r.cs { + if regC == c { + return true + } + } + return false +} + +// Register adds the Collector c to the registry to be used when Collect is +// called. +// +// This method may panic if the Collector's signal Set is not valid, or if the +// Collector has already been added. +// +// The order which Collectors are added is preserved. +func (r *Registry) Register(c Collector) { + validateCollector(c) + if r.containsCollector(c) { + panic(fmt.Sprintf("collector %s has already been registered", c.EmptySet().Namespace())) + } + if err := signal.ValidateSet(c.EmptySet()); err != nil { + panic(err) + } + r.cs = append(r.cs, c) +} + +func (r *Registry) collectorsForRepository(repo projectrepo.Repo) []Collector { + // Check for duplicates using a map to preserve the insertion order + // of the collectors. + exists := make(map[signal.Namespace]empty) + var res []Collector + for _, c := range r.cs { + if !c.IsSupported(repo) { + continue + } + if _, ok := exists[c.EmptySet().Namespace()]; ok { + // This key'd collector already exists for this repo. + panic("") + } + // Record that we have seen this key + exists[c.EmptySet().Namespace()] = empty{} + res = append(res, c) + } + return res +} + +// EmptySets returns all the empty signal Sets for all the registered +// Collectors. +// +// This result can be used to determine all the signals that are defined. +// +// The order of each empty Set is the same as the order of registration. If two +// Collectors return a Set with the same Namespace, only the first Set will be +// included. +func (r *Registry) EmptySets() []signal.Set { + exists := make(map[signal.Namespace]empty) + var ss []signal.Set + for _, c := range r.cs { + // skip existing namespaces + if _, ok := exists[c.EmptySet().Namespace()]; ok { + continue + } + ss = append(ss, c.EmptySet()) + } + return ss +} + +// Collect will collect all the signals for the given repo. +func (r *Registry) Collect(ctx context.Context, repo projectrepo.Repo) ([]signal.Set, error) { + cs := r.collectorsForRepository(repo) + var ss []signal.Set + for _, c := range cs { + s, err := c.Collect(ctx, repo) + if err != nil { + return nil, err + } + ss = append(ss, s) + } + return ss, nil +} + +// Register registers the collector with the global registry for use during +// calls to Collect(). +// +// See Registry.Register(). +func Register(c Collector) { + globalRegistry.Register(c) +} + +// EmptySet returns all the empty signal Sets for all the Collectors registered +// with the global registry. +// +// See Registry.EmptySets(). +func EmptySets() []signal.Set { + return globalRegistry.EmptySets() +} + +// Collect collects all the signals for the given repo using the Collectors +// registered with the global registry. +// +// See Registry.Collect(). +func Collect(ctx context.Context, r projectrepo.Repo) ([]signal.Set, error) { + return globalRegistry.Collect(ctx, r) +} + +func validateCollector(c Collector) { + // TODO - ensure a collector with the same Namespace as another use + // the same signal.Set +} diff --git a/cmd/collect_signals/github/collector.go b/cmd/collect_signals/github/collector.go new file mode 100644 index 00000000..f6bc1c26 --- /dev/null +++ b/cmd/collect_signals/github/collector.go @@ -0,0 +1,123 @@ +package github + +import ( + "context" + "errors" + "time" + + "github.com/ossf/criticality_score/cmd/collect_signals/github/legacy" + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" + "github.com/ossf/criticality_score/cmd/collect_signals/signal" +) + +type RepoCollector struct { +} + +func (rc *RepoCollector) EmptySet() signal.Set { + return &signal.RepoSet{} +} + +func (rc *RepoCollector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { + ghr, ok := r.(*repo) + if !ok { + return nil, errors.New("project is not a github project") + } + now := time.Now() + + s := &signal.RepoSet{ + URL: signal.Val(r.URL().String()), + Language: signal.Val(ghr.BasicData.PrimaryLanguage.Name), + License: signal.Val(ghr.BasicData.LicenseInfo.Name), + StarCount: signal.Val(ghr.BasicData.StargazerCount), + CreatedAt: signal.Val(ghr.createdAt()), + CreatedSince: signal.Val(legacy.TimeDelta(now, ghr.createdAt(), legacy.SinceDuration)), + UpdatedAt: signal.Val(ghr.updatedAt()), + UpdatedSince: signal.Val(legacy.TimeDelta(now, ghr.updatedAt(), legacy.SinceDuration)), + // Note: the /stats/commit-activity REST endpoint used in the legacy Python codebase is stale. + CommitFrequency: signal.Val(legacy.Round(float64(ghr.BasicData.DefaultBranchRef.Target.Commit.RecentCommits.TotalCount)/52, 2)), + } + ghr.logger.Debug("Fetching contributors") + if contributors, err := legacy.FetchTotalContributors(ctx, ghr.client, ghr.owner(), ghr.name()); err != nil { + return nil, err + } else { + s.ContributorCount.Set(contributors) + } + ghr.logger.Debug("Fetching org count") + if orgCount, err := legacy.FetchOrgCount(ctx, ghr.client, ghr.owner(), ghr.name()); err != nil { + return nil, err + } else { + s.OrgCount.Set(orgCount) + } + ghr.logger.Debug("Fetching releases") + if releaseCount, err := legacy.FetchReleaseCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacyReleaseLookback); err != nil { + return nil, err + } else { + if releaseCount != 0 { + s.RecentReleaseCount.Set(releaseCount) + } else { + timeSinceCreated := int(now.Sub(ghr.createdAt()).Hours()) / 24 + t := (ghr.BasicData.Tags.TotalCount * legacyReleaseLookbackDays) / timeSinceCreated + s.RecentReleaseCount.Set(t) + } + } + return s, nil +} + +func (rc *RepoCollector) IsSupported(p projectrepo.Repo) bool { + _, ok := p.(*repo) + return ok +} + +type IssuesCollector struct { +} + +func (ic *IssuesCollector) EmptySet() signal.Set { + return &signal.IssuesSet{} +} + +func (ic *IssuesCollector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { + ghr, ok := r.(*repo) + if !ok { + return nil, errors.New("project is not a github project") + } + s := &signal.IssuesSet{} + + // TODO: the calculation of the frequency should be moved into the legacy + // package. Ideally this would be behind an struct/interface that allows + // caching and also removes the need to pass client, owner and name to each + // function call. + ghr.logger.Debug("Fetching updated issues") + if up, err := legacy.FetchIssueCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueStateAll, legacy.IssueLookback); err != nil { + return nil, err + } else { + s.UpdatedCount.Set(up) + if up != 0 { + ghr.logger.Debug("Fetching comment frequency") + if comments, err := legacy.FetchIssueCommentCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueLookback); err != nil { + if errors.Is(err, legacy.TooManyResultsError) { + ghr.logger.Debug("Comment count failed with too many result") + s.CommentFrequency.Set(legacy.TooManyCommentsFrequency) + } else { + return nil, err + } + } else { + s.CommentFrequency.Set(legacy.Round(float64(comments)/float64(up), 2)) + } + } else { + s.CommentFrequency.Set(0) + } + } + ghr.logger.Debug("Fetching closed issues") + if closed, err := legacy.FetchIssueCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueStateClosed, legacy.IssueLookback); err != nil { + return nil, err + } else { + s.ClosedCount.Set(closed) + } + + return s, nil +} + +func (ic *IssuesCollector) IsSupported(r projectrepo.Repo) bool { + _, ok := r.(*repo) + return ok +} diff --git a/cmd/collect_signals/github/factory.go b/cmd/collect_signals/github/factory.go new file mode 100644 index 00000000..b8d67b41 --- /dev/null +++ b/cmd/collect_signals/github/factory.go @@ -0,0 +1,38 @@ +package github + +import ( + "context" + "net/url" + + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" + "github.com/ossf/criticality_score/internal/githubapi" + log "github.com/sirupsen/logrus" +) + +type factory struct { + client *githubapi.Client + logger *log.Logger +} + +func NewRepoFactory(client *githubapi.Client, logger *log.Logger) projectrepo.Factory { + return &factory{ + client: client, + logger: logger, + } +} + +func (f *factory) New(ctx context.Context, u *url.URL) (projectrepo.Repo, error) { + p := &repo{ + client: f.client, + origURL: u, + logger: f.logger.WithField("url", u), + } + if err := p.init(ctx); err != nil { + return nil, err + } + return p, nil +} + +func (f *factory) Match(u *url.URL) bool { + return u.Hostname() == "github.com" +} diff --git a/cmd/collect_signals/github/legacy/constants.go b/cmd/collect_signals/github/legacy/constants.go new file mode 100644 index 00000000..a008bead --- /dev/null +++ b/cmd/collect_signals/github/legacy/constants.go @@ -0,0 +1,23 @@ +package legacy + +import ( + "errors" + "time" +) + +const ( + SinceDuration time.Duration = time.Hour * 24 * 30 + IssueLookback time.Duration = time.Hour * 24 * 90 * 24 + + MaxContributorLimit = 5000 + MaxTopContributors = 15 + TooManyContributorsOrgCount = 10 + + TooManyCommentsFrequency = 2.0 + + releasesPerPage = 100 +) + +var ( + TooManyResultsError = errors.New("too many results") +) diff --git a/cmd/collect_signals/github/legacy/contributors.go b/cmd/collect_signals/github/legacy/contributors.go new file mode 100644 index 00000000..9e9f6b1f --- /dev/null +++ b/cmd/collect_signals/github/legacy/contributors.go @@ -0,0 +1,108 @@ +package legacy + +import ( + "context" + "fmt" + "strings" + + "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/internal/githubapi" +) + +// FetchTotalContributors returns the total number of contributors for the given repository. +// +// Results will be capped to MaxContributorLimit. +func FetchTotalContributors(ctx context.Context, c *githubapi.Client, owner, name string) (int, error) { + opts := &github.ListContributorsOptions{ + Anon: "1", + ListOptions: github.ListOptions{PerPage: 1}, // 1 result per page means LastPage is total number of records. + } + cs, resp, err := c.Rest().Repositories.ListContributors(ctx, owner, name, opts) + if errorTooManyContributors(err) { + return MaxContributorLimit, nil + } + if err != nil { + return 0, err + } + if resp.NextPage == 0 { + return len(cs), nil + } + total := resp.LastPage + if total > MaxContributorLimit { + return MaxContributorLimit, nil + } + return total, nil +} + +// FetchOrgCount returns the number of unique orgs/companies for the top +// MaxTopContributors of a given repository. +// +// If there are too many contributors for the given repo, the number returned +// will be TooManyContributorsOrgCount. +func FetchOrgCount(ctx context.Context, c *githubapi.Client, owner, name string) (int, error) { + orgFilter := strings.NewReplacer( + "inc.", "", + "llc", "", + "@", "", + " ", "", + ) + + opts := &github.ListContributorsOptions{ + ListOptions: github.ListOptions{ + PerPage: MaxTopContributors, + }, + } + // Get the list of contributors + cs, _, err := c.Rest().Repositories.ListContributors(ctx, owner, name, opts) + if errorTooManyContributors(err) { + return TooManyContributorsOrgCount, nil + } + if err != nil { + return 0, err + } + + // Doing this over REST would take O(n) requests, using GraphQL takes O(1). + userQueries := map[string]string{} + for i, contributor := range cs { + login := contributor.GetLogin() + if login == "" { + continue + } + if strings.HasSuffix(login, "[bot]") { + continue + } + userQueries[fmt.Sprint(i)] = fmt.Sprintf("user(login:\"%s\")", login) + } + if len(userQueries) == 0 { + // We didn't add any users. + return 0, err + } + r, err := githubapi.BatchQuery[struct{ Company string }](ctx, c, userQueries, map[string]any{}) + if err != nil { + return 0, err + } + // Extract the Company from each returned field and add it to the org set. + orgSet := make(map[string]empty) + for _, u := range r { + org := u.Company + if org == "" { + continue + } + org = strings.TrimRight(orgFilter.Replace(strings.ToLower(org)), ",") + orgSet[org] = empty{} + } + return len(orgSet), nil +} + +// errorTooManyContributors returns true if err is a 403 due to too many +// contributors. +func errorTooManyContributors(err error) bool { + if err == nil { + return false + } + e, ok := err.(*github.ErrorResponse) + if !ok { + return false + } + return e.Response.StatusCode == 403 && strings.Contains(e.Message, "list is too large") +} diff --git a/cmd/collect_signals/github/legacy/created.go b/cmd/collect_signals/github/legacy/created.go new file mode 100644 index 00000000..2ea44560 --- /dev/null +++ b/cmd/collect_signals/github/legacy/created.go @@ -0,0 +1,55 @@ +package legacy + +import ( + "context" + "fmt" + "time" + + "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/internal/githubapi" +) + +// FetchCreatedTime returns the earliest known creation time for a given +// repository based on the commit history, before or equal to earliestSoFar. +// +// Only times before earliestSoFar will be considered. If there is no time before +// earliestSoFar found, the value of earliestSoFar will be returned. +func FetchCreatedTime(ctx context.Context, c *githubapi.Client, owner, name string, earliestSoFar time.Time) (time.Time, error) { + opts := &github.CommitsListOptions{ + Until: earliestSoFar, + ListOptions: github.ListOptions{PerPage: 1}, // 1 result per page means LastPage is total number of records. + } + cs, resp, err := c.Rest().Repositories.ListCommits(ctx, owner, name, opts) + if githubapi.ErrorResponseStatusCode(err) == 409 { + // 409 Conflict can happen if the Git Repository is empty. + return earliestSoFar, nil + } + if err != nil { + return time.Time{}, err + } + // Handle 0 or 1 result. + if resp.NextPage == 0 || resp.LastPage == 1 { + if len(cs) == 0 { + return earliestSoFar, nil + } else { + return cs[0].GetCommit().GetCommitter().GetDate(), nil + } + } + // It is possible that new commits are pushed between the previous + // request and the next. If we detect that we are not on LastPage + // try again a few more times. + attempts := 5 + for opts.Page != resp.LastPage && attempts > 0 { + opts.Page = resp.LastPage + cs, resp, err = c.Rest().Repositories.ListCommits(ctx, owner, name, opts) + if err != nil { + return time.Time{}, err + } + attempts-- + } + if len(cs) != 0 { + return cs[len(cs)-1].GetCommit().GetCommitter().GetDate(), nil + } else { + return time.Time{}, fmt.Errorf("commits disappeared for GitHub repo '%s/%s'", owner, name) + } +} diff --git a/cmd/collect_signals/github/legacy/issues.go b/cmd/collect_signals/github/legacy/issues.go new file mode 100644 index 00000000..4bf67ad7 --- /dev/null +++ b/cmd/collect_signals/github/legacy/issues.go @@ -0,0 +1,62 @@ +package legacy + +import ( + "context" + "time" + + "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/internal/githubapi" +) + +type IssueState string + +const ( + IssueStateAll = "all" + IssueStateOpen = "open" + IssueStateClosed = "closed" +) + +// FetchIssueCount returns the total number of issues for a given repo in a +// given state, across the past lookback duration. +// +// This count includes both issues and pull requests. +func FetchIssueCount(ctx context.Context, c *githubapi.Client, owner, name string, state IssueState, lookback time.Duration) (int, error) { + opts := &github.IssueListByRepoOptions{ + Since: time.Now().UTC().Add(-lookback), + State: string(state), + ListOptions: github.ListOptions{PerPage: 1}, // 1 result per page means LastPage is total number of records. + } + is, resp, err := c.Rest().Issues.ListByRepo(ctx, owner, name, opts) + if err != nil { + return 0, err + } + if resp.NextPage == 0 { + return len(is), nil + } + return resp.LastPage, nil +} + +// FetchIssueCommentCount returns the total number of comments for a given repo +// across all issues and pull requests, for the past lookback duration. +// +// If the exact number if unable to be returned because there are too many +// results, a TooManyResultsError will be returned. +func FetchIssueCommentCount(ctx context.Context, c *githubapi.Client, owner, name string, lookback time.Duration) (int, error) { + since := time.Now().UTC().Add(-lookback) + opts := &github.IssueListCommentsOptions{ + Since: &since, + ListOptions: github.ListOptions{PerPage: 1}, // 1 result per page means LastPage is total number of records. + } + cs, resp, err := c.Rest().Issues.ListComments(ctx, owner, name, 0, opts) + // The API returns 5xx responses if there are too many comments. + if c := githubapi.ErrorResponseStatusCode(err); 500 <= c && c < 600 { + return 0, TooManyResultsError + } + if err != nil { + return 0, err + } + if resp.NextPage == 0 { + return len(cs), nil + } + return resp.LastPage, nil +} diff --git a/cmd/collect_signals/github/legacy/releases.go b/cmd/collect_signals/github/legacy/releases.go new file mode 100644 index 00000000..2186c648 --- /dev/null +++ b/cmd/collect_signals/github/legacy/releases.go @@ -0,0 +1,93 @@ +package legacy + +import ( + "context" + "errors" + "io" + "time" + + "github.com/ossf/criticality_score/internal/githubapi" + "github.com/ossf/criticality_score/internal/githubapi/pagination" + "github.com/shurcooL/githubv4" +) + +type repoReleasesQuery struct { + Repository struct { + Releases struct { + TotalCount int + Nodes []struct { + Release struct { + CreatedAt time.Time + } `graphql:"... on Release"` + } + PageInfo struct { + EndCursor string + HasNextPage bool + } + } `graphql:"releases(orderBy:{direction:DESC, field:CREATED_AT}, first: $perPage, after: $endCursor)"` + } `graphql:"repository(owner: $repositoryOwner, name: $repositoryName)"` +} + +// Total implements the pagination.PagedQuery interface +func (r *repoReleasesQuery) Total() int { + return r.Repository.Releases.TotalCount +} + +// Length implements the pagination.PagedQuery interface +func (r *repoReleasesQuery) Length() int { + return len(r.Repository.Releases.Nodes) +} + +// Get implements the pagination.PagedQuery interface +func (r *repoReleasesQuery) Get(i int) any { + return r.Repository.Releases.Nodes[i].Release.CreatedAt +} + +// HasNextPage implements the pagination.PagedQuery interface +func (r *repoReleasesQuery) HasNextPage() bool { + return r.Repository.Releases.PageInfo.HasNextPage +} + +// NextPageVars implements the pagination.PagedQuery interface +func (r *repoReleasesQuery) NextPageVars() map[string]any { + if r.Repository.Releases.PageInfo.EndCursor == "" { + return map[string]any{ + "endCursor": (*githubv4.String)(nil), + } + } else { + return map[string]any{ + "endCursor": githubv4.String(r.Repository.Releases.PageInfo.EndCursor), + } + } +} + +func FetchReleaseCount(ctx context.Context, c *githubapi.Client, owner, name string, lookback time.Duration) (int, error) { + s := &repoReleasesQuery{} + vars := map[string]any{ + "perPage": githubv4.Int(releasesPerPage), + "endCursor": githubv4.String(owner), + "repositoryOwner": githubv4.String(owner), + "repositoryName": githubv4.String(name), + } + cursor, err := pagination.Query(ctx, c.GraphQL(), s, vars) + if err != nil { + return 0, err + } + cutoff := time.Now().UTC().Add(-lookback) + total := 0 + for { + obj, err := cursor.Next() + if obj == nil && errors.Is(err, io.EOF) { + break + } else if err != nil { + return 0, err + } + releaseCreated := obj.(time.Time) + if releaseCreated.Before(cutoff) { + break + } else { + total++ + } + } + return total, nil +} diff --git a/cmd/collect_signals/github/legacy/util.go b/cmd/collect_signals/github/legacy/util.go new file mode 100644 index 00000000..df39b989 --- /dev/null +++ b/cmd/collect_signals/github/legacy/util.go @@ -0,0 +1,25 @@ +package legacy + +import ( + "math" + "time" +) + +// empty is a convenience wrapper for the empty struct. +type empty struct{} + +func TimeDelta(a, b time.Time, u time.Duration) int { + var d time.Duration + if a.Before(b) { + d = b.Sub(a) + } else { + d = a.Sub(b) + } + return int(d / u) +} + +// Round will return v approximately rounded to a precision of p decimal places. +func Round(v float64, p int) float64 { + m := math.Pow10(p) + return math.Round(v*m) / m +} diff --git a/cmd/collect_signals/github/queries.go b/cmd/collect_signals/github/queries.go new file mode 100644 index 00000000..10a9d723 --- /dev/null +++ b/cmd/collect_signals/github/queries.go @@ -0,0 +1,76 @@ +package github + +import ( + "context" + "net/url" + "strings" + "time" + + "github.com/shurcooL/githubv4" +) + +const ( + legacyReleaseLookbackDays = 365 + legacyReleaseLookback = time.Duration(legacyReleaseLookbackDays * 24 * time.Hour) + legacyCommitLookback = time.Duration(365 * 24 * time.Hour) +) + +type basicRepoData struct { + Name string + Owner struct{ Login string } + LicenseInfo struct{ Name string } + StargazerCount int + URL string + MirrorURL string + CreatedAt time.Time + UpdatedAt time.Time + PrimaryLanguage struct { + Name string + } + Watchers struct { + TotalCount int + } + HasIssuesEnabled bool + IsArchived bool + IsDisabled bool + IsEmpty bool + IsMirror bool + + DefaultBranchRef struct { + Target struct { + Commit struct { // this is the last commit + AuthoredDate time.Time + RecentCommits struct { + TotalCount int + } `graphql:"recentcommits:history(since:$legacyCommitLookback)"` + } `graphql:"... on Commit"` + } + } + + Tags struct { + TotalCount int + } `graphql:"refs(refPrefix:\"refs/tags/\")"` +} + +func queryBasicRepoData(ctx context.Context, client *githubv4.Client, u *url.URL) (*basicRepoData, error) { + // Search based on owner and repo name becaues the `repository` query + // better handles changes in ownership and repository name than the + // `resource` query. + // TODO - consider improving support for scp style urls and urls ending in .git + parts := strings.Split(strings.Trim(u.Path, "/"), "/") + owner := parts[0] + name := parts[1] + s := &struct { + Repository basicRepoData `graphql:"repository(owner: $repositoryOwner, name: $repositoryName)"` + }{} + now := time.Now().UTC() + vars := map[string]any{ + "repositoryOwner": githubv4.String(owner), + "repositoryName": githubv4.String(name), + "legacyCommitLookback": githubv4.GitTimestamp{Time: now.Add(-legacyCommitLookback)}, + } + if err := client.Query(ctx, s, vars); err != nil { + return nil, err + } + return &s.Repository, nil +} diff --git a/cmd/collect_signals/github/repo.go b/cmd/collect_signals/github/repo.go new file mode 100644 index 00000000..988f8110 --- /dev/null +++ b/cmd/collect_signals/github/repo.go @@ -0,0 +1,68 @@ +package github + +import ( + "context" + "net/url" + "time" + + "github.com/ossf/criticality_score/cmd/collect_signals/github/legacy" + "github.com/ossf/criticality_score/internal/githubapi" + log "github.com/sirupsen/logrus" +) + +// repo implements the projectrepo.Repo interface for a GitHub repository. +type repo struct { + client *githubapi.Client + origURL *url.URL + logger *log.Entry + + BasicData *basicRepoData + realURL *url.URL + created time.Time +} + +// URL implements the projectrepo.Repo interface +func (r *repo) URL() *url.URL { + return r.realURL +} + +func (r *repo) init(ctx context.Context) error { + if r.BasicData != nil { + // Already finished. Don't init() more than once. + return nil + } + r.logger.Debug("Fetching basic data from GitHub") + data, err := queryBasicRepoData(ctx, r.client.GraphQL(), r.origURL) + if err != nil { + return err + } + r.logger.Debug("Fetching created time") + if created, err := legacy.FetchCreatedTime(ctx, r.client, data.Owner.Login, data.Name, data.CreatedAt); err != nil { + return err + } else { + r.created = created + } + r.realURL, err = url.Parse(data.URL) + if err != nil { + return err + } + // Set BasicData last as it is used to indicate init() has been called. + r.BasicData = data + return nil +} + +func (r *repo) owner() string { + return r.BasicData.Owner.Login +} + +func (r *repo) name() string { + return r.BasicData.Name +} + +func (r *repo) updatedAt() time.Time { + return r.BasicData.DefaultBranchRef.Target.Commit.AuthoredDate +} + +func (r *repo) createdAt() time.Time { + return r.created +} diff --git a/cmd/collect_signals/githubmentions/collector.go b/cmd/collect_signals/githubmentions/collector.go new file mode 100644 index 00000000..88489ea9 --- /dev/null +++ b/cmd/collect_signals/githubmentions/collector.go @@ -0,0 +1,67 @@ +// Package githubmentions provides a Collector that returns a Set for the +// number of mentions a given repository has in commit messages as returned by +// GitHub's search interface. +// +// This signal formed the basis of the original version of dependent count, +// however it is a noisy, unreliable signal. +package githubmentions + +import ( + "context" + "fmt" + "net/url" + "strings" + + "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" + "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/githubapi" +) + +type mentionSet struct { + MentionCount signal.Field[int] `signal:"github_mention_count,legacy"` +} + +func (s *mentionSet) Namespace() signal.Namespace { + return signal.Namespace("github_mentions") +} + +type Collector struct { + client *githubapi.Client +} + +func NewCollector(c *githubapi.Client) *Collector { + return &Collector{ + client: c, + } +} + +func (c *Collector) EmptySet() signal.Set { + return &mentionSet{} +} + +func (c *Collector) IsSupported(r projectrepo.Repo) bool { + return true +} + +func (c *Collector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { + s := &mentionSet{} + if c, err := c.githubSearchTotalCommitMentions(ctx, r.URL()); err != nil { + return nil, err + } else { + s.MentionCount.Set(c) + } + return s, nil +} + +func (c *Collector) githubSearchTotalCommitMentions(ctx context.Context, u *url.URL) (int, error) { + repoName := strings.Trim(u.Path, "/") + opts := &github.SearchOptions{ + ListOptions: github.ListOptions{PerPage: 1}, + } + commits, _, err := c.client.Rest().Search.Commits(ctx, fmt.Sprintf("\"%s\"", repoName), opts) + if err != nil { + return 0, err + } + return commits.GetTotal(), nil +} diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go new file mode 100644 index 00000000..50d9010b --- /dev/null +++ b/cmd/collect_signals/main.go @@ -0,0 +1,191 @@ +package main + +import ( + "bufio" + "context" + "flag" + "fmt" + "io" + "net/http" + "net/url" + "os" + "path" + "strings" + + "github.com/ossf/criticality_score/cmd/collect_signals/collector" + "github.com/ossf/criticality_score/cmd/collect_signals/github" + "github.com/ossf/criticality_score/cmd/collect_signals/githubmentions" + "github.com/ossf/criticality_score/cmd/collect_signals/result" + "github.com/ossf/criticality_score/internal/githubapi" + "github.com/ossf/criticality_score/internal/logflag" + "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" + sclog "github.com/ossf/scorecard/v4/log" + log "github.com/sirupsen/logrus" + //csvutil (it's docs are heaps better!) +) + +const defaultLogLevel = log.InfoLevel + +var logFlag = logflag.Level(defaultLogLevel) + +func init() { + flag.Var(&logFlag, "log", "set the `level` of logging.") + outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") + flag.Usage = func() { + cmdName := path.Base(os.Args[0]) + w := flag.CommandLine.Output() + fmt.Fprintf(w, "Usage:\n %s [FLAGS]... IN_FILE... OUT_FILE\n\n", cmdName) + fmt.Fprintf(w, "Collects signals for each project repository listed.\n") + fmt.Fprintf(w, "IN_FILE must be either a file or - to read from stdin.\n") + fmt.Fprintf(w, "OUT_FILE must be either be a file or - to write to stdout.\n") + fmt.Fprintf(w, "\nFlags:\n") + flag.PrintDefaults() + } +} + +func main() { + flag.Parse() + + logger := log.New() + logger.SetLevel(logFlag.Level()) + + // roundtripper requires us to use the scorecard logger. + scLogger := sclog.NewLogrusLogger(logger) + + if flag.NArg() < 2 { + logger.Error("Must have at least one input file and an output file specified.") + os.Exit(2) + } + lastArg := flag.NArg() - 1 + + // Open all the in-files for reading + var readers []io.Reader + consumingStdin := false + for _, inFilename := range flag.Args()[:lastArg] { + if inFilename == "-" && !consumingStdin { + logger.Info("Reading from stdin") + // Only add stdin once. + consumingStdin = true + readers = append(readers, os.Stdin) + continue + } + logger.WithFields(log.Fields{ + "filename": inFilename, + }).Debug("Reading from file") + f, err := os.Open(inFilename) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "filename": inFilename, + }).Error("Failed to open an input file") + os.Exit(2) + } + defer f.Close() + readers = append(readers, f) + } + r := io.MultiReader(readers...) + + // Open the out-file for writing + outFilename := flag.Args()[lastArg] + w, err := outfile.Open(outFilename) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "filename": outFilename, + }).Error("Failed to open file for output") + os.Exit(2) + } + defer w.Close() + + ctx := context.Background() + + // Prepare a client for communicating with GitHub's GraphQLv4 API and Restv3 API + rt := roundtripper.NewTransport(ctx, scLogger) + httpClient := &http.Client{ + Transport: rt, + } + ghClient := githubapi.NewClient(httpClient) + + ghRepoFactory := github.NewRepoFactory(ghClient, logger) + + // Register all the collectors that are supported. + collector.Register(&github.RepoCollector{}) + collector.Register(&github.IssuesCollector{}) + collector.Register(githubmentions.NewCollector(ghClient)) + + // Prepare the output writer + out := result.NewCsvWriter(w, collector.EmptySets()) + + // Read in each line from the input files + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + + u, err := url.Parse(strings.TrimSpace(line)) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "url": line, + }).Error("Failed to parse project url") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } + logger.WithFields(log.Fields{ + "url": u.String(), + }).Debug("Parsed project url") + + // TODO: Create a resolver in the project package. + r, err := ghRepoFactory.New(ctx, u) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "url": u.String(), + }).Warning("Failed to create project") + continue + //os.Exit(1) // TODO: add a flag to continue or abort on failure + // TODO: we should have an error that indicates that the URL/Project + // should be skipped/ignored. + } + + // TODO: p.URL() should be checked to see if it has already been processed. + + // Collect the signals for the given project + logger.WithFields(log.Fields{ + "url": u.String(), + }).Info("Collecting") + ss, err := collector.Collect(ctx, r) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "url": r.URL().String(), + }).Error("Failed to collect signals for project") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } + + rec := out.Record() + for _, s := range ss { + if err := rec.WriteSignalSet(s); err != nil { + logger.WithFields(log.Fields{ + "error": err, + "url": r.URL().String(), + }).Error("Failed to write signal set") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } + } + if err := rec.Done(); err != nil { + logger.WithFields(log.Fields{ + "error": err, + "repository": line, + }).Error("Failed to complete record") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } + } + if err := scanner.Err(); err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed while reading input") + os.Exit(2) + } + + // TODO: track metrics as we are running to measure coverage of data +} diff --git a/cmd/collect_signals/projectrepo/repo.go b/cmd/collect_signals/projectrepo/repo.go new file mode 100644 index 00000000..6967a5fc --- /dev/null +++ b/cmd/collect_signals/projectrepo/repo.go @@ -0,0 +1,24 @@ +package projectrepo + +import ( + "context" + "net/url" +) + +// Repo is the core interface representing a project's source repository. +type Repo interface { + URL() *url.URL +} + +// Factory is used to obtain new instances of Repo. +type Factory interface { + // New returns a new instance of Repo for the supplied URL. + // + // If the project is not valid for use, or there is an issue creating the + // the Project will be nil and an error will be returned. + New(context.Context, *url.URL) (Repo, error) + + // Match returns true if this factory can create a new instance of Repo + // repository for the given repository URL. + Match(*url.URL) bool +} diff --git a/cmd/collect_signals/result/csv.go b/cmd/collect_signals/result/csv.go new file mode 100644 index 00000000..38c9ce38 --- /dev/null +++ b/cmd/collect_signals/result/csv.go @@ -0,0 +1,96 @@ +package result + +import ( + "encoding/csv" + "fmt" + "io" + "time" + + "github.com/ossf/criticality_score/cmd/collect_signals/signal" +) + +type csvWriter struct { + header []string + w *csv.Writer + headerWritten bool +} + +func headerFromSignalSets(sets []signal.Set) []string { + var hs []string + for _, s := range sets { + if err := signal.ValidateSet(s); err != nil { + panic(err) + } + hs = append(hs, signal.SetFields(s, true)...) + } + return hs +} + +func NewCsvWriter(w io.Writer, emptySets []signal.Set) Writer { + return &csvWriter{ + header: headerFromSignalSets(emptySets), + w: csv.NewWriter(w), + } +} + +func (w *csvWriter) Record() RecordWriter { + return &csvRecord{ + values: make(map[string]string), + sink: w, + } +} + +func (s *csvWriter) maybeWriteHeader() error { + if s.headerWritten { + return nil + } + s.headerWritten = true + return s.w.Write(s.header) +} + +func (s *csvWriter) writeRecord(c *csvRecord) error { + if err := s.maybeWriteHeader(); err != nil { + return err + } + var rec []string + for _, k := range s.header { + rec = append(rec, c.values[k]) + } + if err := s.w.Write(rec); err != nil { + return err + } + s.w.Flush() + return s.w.Error() +} + +type csvRecord struct { + values map[string]string + sink *csvWriter +} + +func (r *csvRecord) WriteSignalSet(s signal.Set) error { + data := signal.SetAsMap(s, true) + for k, v := range data { + if s, err := marshalValue(v); err != nil { + return err + } else { + r.values[k] = s + } + } + return nil +} + +func (r *csvRecord) Done() error { + return r.sink.writeRecord(r) +} + +func marshalValue(value any) (string, error) { + switch v := value.(type) { + case bool, int, int16, int32, int64, uint, uint16, uint32, uint64, byte, float32, float64, string: + return fmt.Sprintf("%v", value), nil + case time.Time: + return v.Format(time.RFC3339), nil + default: + return "", MarshalError + } +} diff --git a/cmd/collect_signals/result/emitter.go b/cmd/collect_signals/result/emitter.go new file mode 100644 index 00000000..0213a967 --- /dev/null +++ b/cmd/collect_signals/result/emitter.go @@ -0,0 +1,27 @@ +package result + +import ( + "errors" + + "github.com/ossf/criticality_score/cmd/collect_signals/signal" +) + +var ( + MarshalError = errors.New("failed to marshal value") +) + +type RecordWriter interface { + // WriteSignalSet is used to output the value for a signal.Set for a record. + WriteSignalSet(signal.Set) error + + // Done indicates that all the fields for the record have been written and + // record is complete. + Done() error +} + +type Writer interface { + //WriteAll([]signal.Set) error + + // Record returns a RecordWriter that can be used to write a new record. + Record() RecordWriter +} diff --git a/cmd/collect_signals/signal/issues.go b/cmd/collect_signals/signal/issues.go new file mode 100644 index 00000000..6154f863 --- /dev/null +++ b/cmd/collect_signals/signal/issues.go @@ -0,0 +1,11 @@ +package signal + +type IssuesSet struct { + UpdatedCount Field[int] `signal:"updated_issues_count,legacy"` + ClosedCount Field[int] `signal:"closed_issues_count,legacy"` + CommentFrequency Field[float64] `signal:"issue_comment_frequency,legacy"` +} + +func (r *IssuesSet) Namespace() Namespace { + return NamespaceIssues +} diff --git a/cmd/collect_signals/signal/repo.go b/cmd/collect_signals/signal/repo.go new file mode 100644 index 00000000..c05fff81 --- /dev/null +++ b/cmd/collect_signals/signal/repo.go @@ -0,0 +1,26 @@ +package signal + +import "time" + +type RepoSet struct { + URL Field[string] + Language Field[string] + License Field[string] + + StarCount Field[int] + CreatedAt Field[time.Time] + UpdatedAt Field[time.Time] + + CreatedSince Field[int] `signal:"legacy"` + UpdatedSince Field[int] `signal:"legacy"` + + ContributorCount Field[int] `signal:"legacy"` + OrgCount Field[int] `signal:"legacy"` + + CommitFrequency Field[float64] `signal:"legacy"` + RecentReleaseCount Field[int] `signal:"legacy"` +} + +func (r *RepoSet) Namespace() Namespace { + return NamespaceRepo +} diff --git a/cmd/collect_signals/signal/signal.go b/cmd/collect_signals/signal/signal.go new file mode 100644 index 00000000..c319f8ad --- /dev/null +++ b/cmd/collect_signals/signal/signal.go @@ -0,0 +1,241 @@ +package signal + +import ( + "fmt" + "reflect" + "regexp" + "strings" + "time" + + "github.com/iancoleman/strcase" +) + +type Namespace string + +func (ns Namespace) String() string { + return string(ns) +} + +const ( + // nameSeparator is used to separate the namespace from the field name. + nameSeparator = '.' + + // namespaceLegacy is an internal namespace used for fields that provide + // compatibility with the legacy python implementation. + namespaceLegacy Namespace = "legacy" + + // The following constants are used while parsing the tags for the struct + // fields in a Set. + fieldTagName = "signal" + fieldTagIgnore = "-" + fieldTagLegacy = "legacy" + fieldTagSeperator = "," +) + +const ( + NamespaceRepo Namespace = "repo" + NamespaceIssues Namespace = "issues" +) + +var ( + // validName is used to validate namespace and field names. + validName = regexp.MustCompile("^[a-z0-9_]+$") + + // valuerType caches the reflect.Type representation of the valuer + // interface. + valuerType = reflect.TypeOf((*valuer)(nil)).Elem() +) + +type SupportedType interface { + ~int | ~int8 | ~int16 | ~int32 | ~int64 | + ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr | + ~float32 | ~float64 | + ~string | time.Time +} + +// valuer is provides access to the field's value without needing to use +// the concrete generic. It is also a marker interface used to identify the +// Signal field in a struct. +type valuer interface { + Value() any +} + +type Field[T SupportedType] struct { + value T + set bool +} + +func (s *Field[T]) Set(v T) { + s.value = v + s.set = true +} + +func (s *Field[T]) Get() T { + if !s.set { + var zero T + return zero + } + return s.value +} + +func (s *Field[T]) IsSet() bool { + return s.set +} + +func (s *Field[T]) Unset() { + s.set = false +} + +func (s Field[T]) Value() any { + if !s.set { + return nil + } else { + return s.value + } +} + +// Val is used to create a Field instance that is already set with the value v. +// +// This method is particularly useful when creating an new instance of a Set. +// +// s = &FooSet{ +// myField: signal.Val("hello, world!") +// } +func Val[T SupportedType](v T) Field[T] { + var f Field[T] + f.Set(v) + return f +} + +type Set interface { + Namespace() Namespace +} + +type fieldConfig struct { + name string + legacy bool +} + +// ValidateSet tests whether a Set is valid. +// +// An invalid Set will return an error with the first test that failed. A valid +// Set will return nil. +func ValidateSet(s Set) error { + if ns := string(s.Namespace()); !validName.MatchString(ns) { + return fmt.Errorf("namespace '%s' contains invalid characters", ns) + } + return iterSetFields(s, func(f *fieldConfig, _ any) error { + if !validName.MatchString(f.name) { + return fmt.Errorf("field name '%s' contains invalid character", f.name) + } + return nil + }) +} + +// parseStructField processes a field sf in a Set to extract the field's +// congiration from the field's tag. +// +// If the field is not of type Field, or is configured to be ignored, this +// method will return nil. +func parseStructField(sf reflect.StructField) *fieldConfig { + if !sf.Type.Implements(valuerType) { + // Ignore fields that don't implement the valuer interface as + // these are not Field and should be skipped. + return nil + } + tag := sf.Tag.Get(fieldTagName) + if tag == fieldTagIgnore { + // The field is marked to be ignored, so skip it. + return nil + } + f := &fieldConfig{ + name: strcase.ToSnake(sf.Name), + legacy: false, + } + if tag != "" { + parts := strings.Split(tag, fieldTagSeperator) + for _, p := range parts { + switch strings.TrimSpace(p) { + case "": + // noop + case fieldTagLegacy: + f.legacy = true + default: + f.name = p + } + } + } + return f +} + +// iterSetFields is an internal helper for looping across all the Fields in s. +// It is also responsible for parsing the struct's tag. +// +// The function cb is called for each field that will be present in the output. +func iterSetFields(s Set, cb func(*fieldConfig, any) error) error { + vs := reflect.ValueOf(s).Elem() + tfs := reflect.VisibleFields(reflect.TypeOf(s).Elem()) + for _, sf := range tfs { + f := parseStructField(sf) + if f == nil { + continue + } + val := vs.FieldByIndex(sf.Index).Interface().(valuer) + // Grab the value and call the cb with all the bits + v := val.Value() + if err := cb(f, v); err != nil { + return err + } + } + return nil +} + +// SetFields returns a slice containing the names of the fields for s. +// +// If namespace is true the field names will be prefixed with the namespace. +func SetFields(s Set, namespace bool) []string { + var fs []string + prefix := "" + legacyPrefix := "" + if namespace { + prefix = fmt.Sprintf("%s%c", s.Namespace(), nameSeparator) + legacyPrefix = fmt.Sprintf("%s%c", namespaceLegacy, nameSeparator) + } + _ = iterSetFields(s, func(f *fieldConfig, _ any) error { + if f.legacy { + fs = append(fs, legacyPrefix+f.name) + } else { + fs = append(fs, prefix+f.name) + } + return nil + }) + return fs +} + +// SetValues returns a slice containing the values for each field for s. +// +// The values are either `nil` if the Field is not set, or the value that was +// set. +func SetValues(s Set) []any { + var vs []any + _ = iterSetFields(s, func(_ *fieldConfig, v any) error { + vs = append(vs, v) + return nil + }) + return vs +} + +// SetAsMap returns a map where each field name is mapped to the value of the +// field. +// +// Fields are named as returned by SetFields and values are the same as those +// returned by SetValues. +func SetAsMap(s Set, namespace bool) map[string]any { + fs := SetFields(s, namespace) + vs := SetValues(s) + m := make(map[string]any) + for i := range fs { + m[fs[i]] = vs[i] + } + return m +} diff --git a/cmd/enumerate_github/githubsearch/repos.go b/cmd/enumerate_github/githubsearch/repos.go index 7076378b..0177fcf2 100644 --- a/cmd/enumerate_github/githubsearch/repos.go +++ b/cmd/enumerate_github/githubsearch/repos.go @@ -5,7 +5,7 @@ import ( "fmt" "io" - "github.com/ossf/criticality_score/cmd/enumerate_github/pagination" + "github.com/ossf/criticality_score/internal/githubapi/pagination" "github.com/shurcooL/githubv4" log "github.com/sirupsen/logrus" ) @@ -42,7 +42,7 @@ func (q *repoQuery) Length() int { } // Get implements the pagination.PagedQuery interface -func (q *repoQuery) Get(i int) interface{} { +func (q *repoQuery) Get(i int) any { return q.Search.Nodes[i].Repository } @@ -52,13 +52,13 @@ func (q *repoQuery) HasNextPage() bool { } // NextPageVars implements the pagination.PagedQuery interface -func (q *repoQuery) NextPageVars() map[string]interface{} { +func (q *repoQuery) NextPageVars() map[string]any { if q.Search.PageInfo.EndCursor == "" { - return map[string]interface{}{ + return map[string]any{ "endCursor": (*githubv4.String)(nil), } } else { - return map[string]interface{}{ + return map[string]any{ "endCursor": githubv4.String(q.Search.PageInfo.EndCursor), } } @@ -77,7 +77,7 @@ func (re *Searcher) runRepoQuery(q string) (*pagination.Cursor, error) { re.logger.WithFields(log.Fields{ "query": q, }).Debug("Searching GitHub") - vars := map[string]interface{}{ + vars := map[string]any{ "query": githubv4.String(q), "perPage": githubv4.Int(re.perPage), } @@ -99,7 +99,7 @@ func (re *Searcher) runRepoQuery(q string) (*pagination.Cursor, error) { // The algorithm fails if the last star value plus overlap has the same or larger value as the // previous iteration. func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, emitter func(string)) error { - repos := make(map[string]struct{}) + repos := make(map[string]empty) maxStars := -1 stars := 0 for { diff --git a/docs/design/milestone_1.md b/docs/design/milestone_1.md index 4b7aaef0..7ea6f807 100644 --- a/docs/design/milestone_1.md +++ b/docs/design/milestone_1.md @@ -272,7 +272,7 @@ following: * Lowercase characters * Numbers -* Underscores. +* Underscores The following restrictions further apply to `[collector]` names: @@ -302,10 +302,16 @@ Supported scalars can be: * Date * DateTime -All Dates and DateTimes must be in UTC. +All Dates and DateTimes must be in UTC and will be output in the +RFC3339/ISO8601 format: `YYYY-MM-DDTHH:mm:ssZ`. (See +[`time.RFC3339`](https://pkg.go.dev/time#pkg-constants)) Strings will support Unicode. +Null values for scalars are supported. A null value indicates that the signal +could not be collected. To simplify output parsing, an empty string is +equivalent to a null string and is to be interpreted as a null string. + #### Batching (out of scope) More efficient usage of GitHub's APIs can be achieved by batching together diff --git a/go.mod b/go.mod index 08cab178..8060cb71 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,8 @@ module github.com/ossf/criticality_score go 1.18 require ( + github.com/google/go-github/v44 v44.1.0 + github.com/iancoleman/strcase v0.2.0 github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 github.com/sirupsen/logrus v1.8.1 diff --git a/go.sum b/go.sum index 3a0ca563..5d82bd4f 100644 --- a/go.sum +++ b/go.sum @@ -45,12 +45,16 @@ github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= +github.com/google/go-github/v44 v44.1.0 h1:shWPaufgdhr+Ad4eo/pZv9ORTxFpsxPEPEuuXAKIQGA= +github.com/google/go-github/v44 v44.1.0/go.mod h1:iWn00mWcP6PRWHhXm0zuFJ8wbEjE5AGO5D5HXYM4zgw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= +github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= @@ -121,7 +125,6 @@ golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3 golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= diff --git a/internal/githubapi/batch.go b/internal/githubapi/batch.go new file mode 100644 index 00000000..fa06a8e0 --- /dev/null +++ b/internal/githubapi/batch.go @@ -0,0 +1,46 @@ +package githubapi + +import ( + "context" + "fmt" + "reflect" + "strings" +) + +// BatchQuery can be used to batch a set of requests together to GitHub's +// GraphQL API. +func BatchQuery[T any](ctx context.Context, c *Client, queries map[string]string, vars map[string]any) (map[string]T, error) { + // Create a query using reflection (see https://github.com/shurcooL/githubv4/issues/17) + // for when we don't know the exact query before runtime. + var t T + fieldType := reflect.TypeOf(t) + var fields []reflect.StructField + fieldToKey := map[string]string{} + idx := 0 + for key, q := range queries { + name := fmt.Sprintf("Field%d", idx) + fieldToKey[name] = key + fields = append(fields, reflect.StructField{ + Name: name, + Type: fieldType, + Tag: reflect.StructTag(fmt.Sprintf(`graphql:"field%d:%s"`, idx, strings.ReplaceAll(q, "\"", "\\\""))), + }) + idx++ + } + // TODO: an upper bound should be added + if len(fields) == 0 { + // TODO: consider just returning an empty result set rather than panicing. + panic("no query to run") + } + q := reflect.New(reflect.StructOf(fields)).Elem() + if err := c.GraphQL().Query(ctx, q.Addr().Interface(), vars); err != nil { + return nil, err + } + res := map[string]T{} + for _, sf := range reflect.VisibleFields(q.Type()) { + key := fieldToKey[sf.Name] + v := q.FieldByIndex(sf.Index) + res[key] = v.Interface().(T) + } + return res, nil +} diff --git a/internal/githubapi/client.go b/internal/githubapi/client.go new file mode 100644 index 00000000..bc72206e --- /dev/null +++ b/internal/githubapi/client.go @@ -0,0 +1,30 @@ +package githubapi + +import ( + "net/http" + + "github.com/google/go-github/v44/github" + "github.com/shurcooL/githubv4" +) + +type Client struct { + restClient *github.Client + graphClient *githubv4.Client +} + +func NewClient(client *http.Client) *Client { + c := &Client{ + restClient: github.NewClient(client), + graphClient: githubv4.NewClient(client), + } + + return c +} + +func (c *Client) Rest() *github.Client { + return c.restClient +} + +func (c *Client) GraphQL() *githubv4.Client { + return c.graphClient +} diff --git a/internal/githubapi/errors.go b/internal/githubapi/errors.go new file mode 100644 index 00000000..c7d490cd --- /dev/null +++ b/internal/githubapi/errors.go @@ -0,0 +1,19 @@ +package githubapi + +import "github.com/google/go-github/v44/github" + +// ErrorResponseStatusCode will unwrap a github.ErrorResponse and return the +// status code inside. +// +// If the error is nil, or not an ErrorResponse it will return a status code of +// 0. +func ErrorResponseStatusCode(err error) int { + if err == nil { + return 0 + } + e, ok := err.(*github.ErrorResponse) + if !ok { + return 0 + } + return e.Response.StatusCode +} diff --git a/cmd/enumerate_github/pagination/pagination.go b/internal/githubapi/pagination/pagination.go similarity index 88% rename from cmd/enumerate_github/pagination/pagination.go rename to internal/githubapi/pagination/pagination.go index eb6d402b..ecf60696 100644 --- a/cmd/enumerate_github/pagination/pagination.go +++ b/internal/githubapi/pagination/pagination.go @@ -12,20 +12,20 @@ import ( type PagedQuery interface { Total() int Length() int - Get(int) interface{} + Get(int) any HasNextPage() bool - NextPageVars() map[string]interface{} + NextPageVars() map[string]any } type Cursor struct { ctx context.Context client *githubv4.Client query PagedQuery - vars map[string]interface{} + vars map[string]any cur int } -func Query(ctx context.Context, client *githubv4.Client, query PagedQuery, vars map[string]interface{}) (*Cursor, error) { +func Query(ctx context.Context, client *githubv4.Client, query PagedQuery, vars map[string]any) (*Cursor, error) { c := &Cursor{ ctx: ctx, client: client, @@ -62,7 +62,7 @@ func (c *Cursor) Total() int { return c.query.Total() } -func (c *Cursor) Next() (interface{}, error) { +func (c *Cursor) Next() (any, error) { if c.atEndOfPage() { // There are no more nodes in this page, so we need another page. if c.isLastPage() { From 9da2146b70c3ca001415734cd3cb34942bf2d8ab Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 1 Jun 2022 09:25:18 +1000 Subject: [PATCH 059/172] Fix a div by zero bug when daysSinceCreated == 0, and there are tags. (#121) --- cmd/collect_signals/github/collector.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cmd/collect_signals/github/collector.go b/cmd/collect_signals/github/collector.go index f6bc1c26..07891300 100644 --- a/cmd/collect_signals/github/collector.go +++ b/cmd/collect_signals/github/collector.go @@ -55,9 +55,13 @@ func (rc *RepoCollector) Collect(ctx context.Context, r projectrepo.Repo) (signa if releaseCount != 0 { s.RecentReleaseCount.Set(releaseCount) } else { - timeSinceCreated := int(now.Sub(ghr.createdAt()).Hours()) / 24 - t := (ghr.BasicData.Tags.TotalCount * legacyReleaseLookbackDays) / timeSinceCreated - s.RecentReleaseCount.Set(t) + daysSinceCreated := int(now.Sub(ghr.createdAt()).Hours()) / 24 + if daysSinceCreated > 0 { + t := (ghr.BasicData.Tags.TotalCount * legacyReleaseLookbackDays) / daysSinceCreated + s.RecentReleaseCount.Set(t) + } else { + s.RecentReleaseCount.Set(0) + } } } return s, nil From d5d2e80dbecb4813985fee0a88b4af8092017ed7 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 1 Jun 2022 09:31:47 +1000 Subject: [PATCH 060/172] Make results/csv thread-safe so it can be used across multiple workers. (#122) --- cmd/collect_signals/result/csv.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/cmd/collect_signals/result/csv.go b/cmd/collect_signals/result/csv.go index 38c9ce38..1f313a6a 100644 --- a/cmd/collect_signals/result/csv.go +++ b/cmd/collect_signals/result/csv.go @@ -4,6 +4,7 @@ import ( "encoding/csv" "fmt" "io" + "sync" "time" "github.com/ossf/criticality_score/cmd/collect_signals/signal" @@ -13,6 +14,9 @@ type csvWriter struct { header []string w *csv.Writer headerWritten bool + + // Prevents concurrent writes to w, and headerWritten. + mu sync.Mutex } func headerFromSignalSets(sets []signal.Set) []string { @@ -41,6 +45,15 @@ func (w *csvWriter) Record() RecordWriter { } func (s *csvWriter) maybeWriteHeader() error { + // Check headerWritten without the lock to avoid holding the lock if the + // header has already been written. + if s.headerWritten { + return nil + } + // Grab the lock and re-check headerWritten just in case another goroutine + // entered the same critical section. Also prevent concurrent writes to w. + s.mu.Lock() + defer s.mu.Unlock() if s.headerWritten { return nil } @@ -56,6 +69,10 @@ func (s *csvWriter) writeRecord(c *csvRecord) error { for _, k := range s.header { rec = append(rec, c.values[k]) } + // Grab the lock when we're ready to write the record to prevent + // concurrent writes to w. + s.mu.Lock() + defer s.mu.Unlock() if err := s.w.Write(rec); err != nil { return err } From 52f2858e850876cec24ff69be08a9ac81efad1e3 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 1 Jun 2022 10:46:54 +1000 Subject: [PATCH 061/172] Adds a Resolver for turning a url into a Repo. (#123) This is particularly useful because we can use the global resolver to avoid passing instances of the ghRepoFactory around in main.go. --- cmd/collect_signals/projectrepo/resolver.go | 58 +++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 cmd/collect_signals/projectrepo/resolver.go diff --git a/cmd/collect_signals/projectrepo/resolver.go b/cmd/collect_signals/projectrepo/resolver.go new file mode 100644 index 00000000..8a29002c --- /dev/null +++ b/cmd/collect_signals/projectrepo/resolver.go @@ -0,0 +1,58 @@ +package projectrepo + +import ( + "context" + "errors" + "net/url" +) + +// ErrorNotFound is returned when there is no factory that can be used for a +// given URL. +var ErrorNotFound = errors.New("factory not found for url") + +var globalResolver = &Resolver{} + +// Resolver is used to resolve a Repo url against a set of Factory instances +// registered with the resolver. +type Resolver struct { + fs []Factory +} + +func (r *Resolver) findFactory(u *url.URL) Factory { + for _, f := range r.fs { + if f.Match(u) { + return f + } + } + return nil +} + +// Register adds the factory f to the set of factories that can be used for +// resolving a url to a Repo. +func (r *Resolver) Register(f Factory) { + r.fs = append(r.fs, f) +} + +// Resolve takes a url u and returns a corresponding instance of Repo if a +// matching factory has been registered. +// +// If a matching factory can not be found an ErrorNotFound will be returned. +// +// The factory may also return an error. +func (r *Resolver) Resolve(ctx context.Context, u *url.URL) (Repo, error) { + f := r.findFactory(u) + if f == nil { + return nil, ErrorNotFound + } + return f.New(ctx, u) +} + +// Register the factory f with the global resolver. +func Register(f Factory) { + globalResolver.Register(f) +} + +// Resolve the given url u with the global resolver. +func Resolve(ctx context.Context, u *url.URL) (Repo, error) { + return globalResolver.Resolve(ctx, u) +} From 54d6c6005eb63501f102bbb2eaa3c1f548161b3e Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 1 Jun 2022 14:33:28 +1000 Subject: [PATCH 062/172] Add a smaller helper library for initing a pool of workers. (#124) --- cmd/enumerate_github/main.go | 17 ++---- internal/workerpool/workerpool.go | 26 ++++++++ internal/workerpool/workerpool_test.go | 85 ++++++++++++++++++++++++++ 3 files changed, 117 insertions(+), 11 deletions(-) create mode 100644 internal/workerpool/workerpool.go create mode 100644 internal/workerpool/workerpool_test.go diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 56ebc6dd..664de405 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -8,12 +8,12 @@ import ( "net/http" "os" "path" - "sync" "time" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" "github.com/ossf/criticality_score/internal/logflag" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/workerpool" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" sclog "github.com/ossf/scorecard/v4/log" "github.com/shurcooL/githubv4" @@ -101,10 +101,7 @@ func init() { // searchWorker waits for a query on the queries channel, starts a search with that query using s // and returns each repository on the results channel. -// -// When the queries channel is closed it will call wg.Done() to signal that the worker has finished. -func searchWorker(s *githubsearch.Searcher, wg *sync.WaitGroup, logger *log.Entry, queries, results chan string) { - defer wg.Done() +func searchWorker(s *githubsearch.Searcher, logger *log.Entry, queries, results chan string) { for q := range queries { total := 0 err := s.ReposByStars(q, *minStarsFlag, *starOverlapFlag, func(repo string) { @@ -196,17 +193,15 @@ func main() { client := githubv4.NewClient(httpClient) baseQuery := *queryFlag - var wg sync.WaitGroup - wg.Add(*workersFlag) queries := make(chan string) results := make(chan string, (*workersFlag)*reposPerPage) // Start the worker goroutines to execute the search queries - for i := 0; i < *workersFlag; i++ { + wait := workerpool.WorkerPool(*workersFlag, func(i int) { workerLogger := logger.WithFields(log.Fields{"worker": i}) s := githubsearch.NewSearcher(ctx, client, workerLogger, githubsearch.PerPage(reposPerPage)) - go searchWorker(s, &wg, workerLogger, queries, results) - } + searchWorker(s, workerLogger, queries, results) + }) // Start a separate goroutine to collect results so worker output is always consumed. done := make(chan bool) @@ -230,7 +225,7 @@ func main() { // Indicate to the workers that we're finished. close(queries) // Wait for the workers to be finished. - wg.Wait() + wait() logger.Debug("Waiting for writer to finish") // Close the results channel now the workers are done. diff --git a/internal/workerpool/workerpool.go b/internal/workerpool/workerpool.go new file mode 100644 index 00000000..1ca19e22 --- /dev/null +++ b/internal/workerpool/workerpool.go @@ -0,0 +1,26 @@ +package workerpool + +import ( + "sync" +) + +// WorkerFunc implements a function that can be used in a WorkerPool. +// +// worker is a unique integer identifying the worker, starting at 0. +type WorkerFunc func(worker int) + +// WorkerPool starts a pool of n workers each running the WorkerFunc w. +// +// Returns a function waitFunc, that when called waits for all workers to +// finish. +func WorkerPool(n int, w WorkerFunc) (waitFunc func()) { + wg := &sync.WaitGroup{} + wg.Add(n) + for i := 0; i < n; i++ { + go func(worker int) { + defer wg.Done() + w(worker) + }(i) + } + return wg.Wait +} diff --git a/internal/workerpool/workerpool_test.go b/internal/workerpool/workerpool_test.go new file mode 100644 index 00000000..2b5667f2 --- /dev/null +++ b/internal/workerpool/workerpool_test.go @@ -0,0 +1,85 @@ +package workerpool_test + +import ( + "sync/atomic" + "testing" + + "github.com/ossf/criticality_score/internal/workerpool" +) + +func TestOneWorker(t *testing.T) { + var counter int32 + wait := workerpool.WorkerPool(1, func(worker int) { + atomic.AddInt32(&counter, 1) + }) + wait() + if counter != 1 { + t.Fatalf("counter = %d; want 1", counter) + } +} + +func TestManyWorkers(t *testing.T) { + var counter int32 + wait := workerpool.WorkerPool(10, func(worker int) { + atomic.AddInt32(&counter, 1) + }) + wait() + if counter != 10 { + t.Fatalf("counter = %d; want 10", counter) + } +} + +func TestUniqueWorkerId(t *testing.T) { + var counters [10]int32 + wait := workerpool.WorkerPool(10, func(worker int) { + atomic.AddInt32(&(counters[worker]), 1) + }) + wait() + for worker, counter := range counters { + if counter != 1 { + t.Fatalf("counters[%d] = %d; want 1", worker, counter) + } + } +} + +func TestExampleWorkload(t *testing.T) { + nums := make(chan int) + doubles := make(chan int) + var results []int + + // Consume the doubles channel + go func() { + for i := range doubles { + results = append(results, i) + } + }() + + // Start a pool of workers + wait := workerpool.WorkerPool(5, func(worker int) { + for n := range nums { + doubles <- n * 2 + } + }) + + // Send 0-9 into the nums channel + for i := 0; i < 10; i++ { + nums <- i + } + + // Close nums which causes the workers to quit + close(nums) + + // Wait for all the workers to be finished + wait() + + // Make sure all were generated + if l := len(results); l != 10 { + t.Fatalf("len(results) = %d; want 10", l) + } + // Make sure the results are actually doubles + for _, r := range results { + if r%2 != 0 || r < 0 || r/2 >= 10 { + t.Fatalf("result = %d, want result to be divisible by 2, and less than 20", r) + } + } +} From b84e8651c115bce15fa28771cc7def8e475559b8 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 1 Jun 2022 15:39:41 +1000 Subject: [PATCH 063/172] Add support for multiple workers to the signal collection (#125) --- cmd/collect_signals/main.go | 116 +++++++++++++++++++++--------------- 1 file changed, 68 insertions(+), 48 deletions(-) diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 50d9010b..5f809025 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -15,19 +15,23 @@ import ( "github.com/ossf/criticality_score/cmd/collect_signals/collector" "github.com/ossf/criticality_score/cmd/collect_signals/github" "github.com/ossf/criticality_score/cmd/collect_signals/githubmentions" + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/cmd/collect_signals/result" "github.com/ossf/criticality_score/internal/githubapi" "github.com/ossf/criticality_score/internal/logflag" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/workerpool" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" sclog "github.com/ossf/scorecard/v4/log" log "github.com/sirupsen/logrus" - //csvutil (it's docs are heaps better!) ) const defaultLogLevel = log.InfoLevel -var logFlag = logflag.Level(defaultLogLevel) +var ( + workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") + logFlag = logflag.Level(defaultLogLevel) +) func init() { flag.Var(&logFlag, "log", "set the `level` of logging.") @@ -44,6 +48,47 @@ func init() { } } +func handleRepo(ctx context.Context, logger *log.Entry, u *url.URL, out result.Writer) { + r, err := projectrepo.Resolve(ctx, u) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Warning("Failed to create project") + // TODO: we should have an error that indicates that the URL/Project + // should be skipped/ignored. + return // TODO: add a flag to continue or abort on failure + } + logger = logger.WithField("canonical_url", r.URL().String()) + + // TODO: p.URL() should be checked to see if it has already been processed. + + // Collect the signals for the given project + logger.Info("Collecting") + ss, err := collector.Collect(ctx, r) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to collect signals for project") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } + + rec := out.Record() + for _, s := range ss { + if err := rec.WriteSignalSet(s); err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to write signal set") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } + } + if err := rec.Done(); err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to complete record") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } +} + func main() { flag.Parse() @@ -100,6 +145,9 @@ func main() { ctx := context.Background() + // Bump the # idle conns per host + http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = *workersFlag * 5 + // Prepare a client for communicating with GitHub's GraphQLv4 API and Restv3 API rt := roundtripper.NewTransport(ctx, scLogger) httpClient := &http.Client{ @@ -107,7 +155,8 @@ func main() { } ghClient := githubapi.NewClient(httpClient) - ghRepoFactory := github.NewRepoFactory(ghClient, logger) + // Register all the Repo factories. + projectrepo.Register(github.NewRepoFactory(ghClient, logger)) // Register all the collectors that are supported. collector.Register(&github.RepoCollector{}) @@ -117,6 +166,15 @@ func main() { // Prepare the output writer out := result.NewCsvWriter(w, collector.EmptySets()) + // Start the workers that process a channel of repo urls. + repos := make(chan *url.URL) + wait := workerpool.WorkerPool(*workersFlag, func(worker int) { + innerLogger := logger.WithField("worker", worker) + for u := range repos { + handleRepo(ctx, innerLogger.WithField("url", u.String()), u, out) + } + }) + // Read in each line from the input files scanner := bufio.NewScanner(r) for scanner.Scan() { @@ -134,51 +192,8 @@ func main() { "url": u.String(), }).Debug("Parsed project url") - // TODO: Create a resolver in the project package. - r, err := ghRepoFactory.New(ctx, u) - if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "url": u.String(), - }).Warning("Failed to create project") - continue - //os.Exit(1) // TODO: add a flag to continue or abort on failure - // TODO: we should have an error that indicates that the URL/Project - // should be skipped/ignored. - } - - // TODO: p.URL() should be checked to see if it has already been processed. - - // Collect the signals for the given project - logger.WithFields(log.Fields{ - "url": u.String(), - }).Info("Collecting") - ss, err := collector.Collect(ctx, r) - if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "url": r.URL().String(), - }).Error("Failed to collect signals for project") - os.Exit(1) // TODO: add a flag to continue or abort on failure - } - - rec := out.Record() - for _, s := range ss { - if err := rec.WriteSignalSet(s); err != nil { - logger.WithFields(log.Fields{ - "error": err, - "url": r.URL().String(), - }).Error("Failed to write signal set") - os.Exit(1) // TODO: add a flag to continue or abort on failure - } - } - if err := rec.Done(); err != nil { - logger.WithFields(log.Fields{ - "error": err, - "repository": line, - }).Error("Failed to complete record") - os.Exit(1) // TODO: add a flag to continue or abort on failure - } + // Send the url to the workers + repos <- u } if err := scanner.Err(); err != nil { logger.WithFields(log.Fields{ @@ -186,6 +201,11 @@ func main() { }).Error("Failed while reading input") os.Exit(2) } + // Close the repos channel to indicate that there is no more input. + close(repos) + + // Wait until all the workers have finished. + wait() // TODO: track metrics as we are running to measure coverage of data } From fd20e1badc16d2987cc17dc8412c40a9b0ecfeba Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 3 Jun 2022 16:08:27 +1000 Subject: [PATCH 064/172] Add a library to handle the retry logic. (#126) This library is written this way to facilitate testing, which I thought was particularly important for retry related logic as it is hard to cover all the various cases during manual testing. --- internal/retry/request.go | 265 +++++++++++++++++++++++++++++++++ internal/retry/request_test.go | 143 ++++++++++++++++++ 2 files changed, 408 insertions(+) create mode 100644 internal/retry/request.go create mode 100644 internal/retry/request_test.go diff --git a/internal/retry/request.go b/internal/retry/request.go new file mode 100644 index 00000000..6940fecf --- /dev/null +++ b/internal/retry/request.go @@ -0,0 +1,265 @@ +package retry + +import ( + "errors" + "net/http" + "time" +) + +const ( + DefaultMaxRetries = 5 + DefaultInitialDuration = 2 * time.Minute +) + +var ( + ErrorNoMoreAttempts = errors.New("request cannot by retried") +) + +type RetryStrategy int + +const ( + NoRetry RetryStrategy = iota + RetryImmediate + RetryWithInitialDelay +) + +// String implements the Stringer interface. +func (s RetryStrategy) String() string { + switch s { + case NoRetry: + return "NoRetry" + case RetryImmediate: + return "RetryImmediate" + case RetryWithInitialDelay: + return "RetryWithInitialDelay" + default: + panic("Invalid RetryStrategy") + } +} + +// A RetryStrategyFn is used to determine whether or not a retry is needed, and +// if so, whether an initial delay is needed or not. +type RetryStrategyFn func(*http.Response) (RetryStrategy, error) + +// A RetryAfterFn is used to parse the delay from the Retry-After header. +// +// The returned time.Duration will be used as the delay. +// +// If the header is not set, or the value cannot be parsed, a Duration of 0 +// must be returned. +type RetryAfterFn func(*http.Response) time.Duration + +// A BackoffFn takes the previous delay and calculates a new, longer delay. +// +// This is used to extend the time between retries. +type BackoffFn func(time.Duration) time.Duration + +// SleepFn must cause the current goroutine to sleep for the allocated Duration. +// +// The usual implementation of this is time.Sleep. This is provided for testing. +type sleepFn func(time.Duration) + +// DefaultBackoff will double the duration d if it is greater than zero, +// otherwise it returns 1 minute. +func DefaultBackoff(d time.Duration) time.Duration { + if d <= 0 { + return time.Minute + } else { + return d * 2 + } +} + +type Options struct { + maxRetries int + initialDelay time.Duration + backoff BackoffFn + sleep sleepFn + retryAfter RetryAfterFn + retryStrategyFuncs []RetryStrategyFn +} +type Option interface { + Apply(*Options) +} +type optionFn func(*Options) + +func (o optionFn) Apply(opts *Options) { + o(opts) +} + +func MaxRetries(max int) Option { + return optionFn(func(o *Options) { + o.maxRetries = max + }) +} + +func Backoff(bo BackoffFn) Option { + return optionFn(func(o *Options) { + o.backoff = bo + }) +} + +func InitialDelay(d time.Duration) Option { + return optionFn(func(o *Options) { + o.initialDelay = d + }) +} + +func RetryAfter(ra RetryAfterFn) Option { + return optionFn(func(o *Options) { + o.retryAfter = ra + }) +} + +func Strategy(rs RetryStrategyFn) Option { + return optionFn(func(o *Options) { + o.retryStrategyFuncs = append(o.retryStrategyFuncs, rs) + }) +} + +func MakeOptions(os ...Option) *Options { + opts := &Options{ + maxRetries: DefaultMaxRetries, + initialDelay: DefaultInitialDuration, + sleep: time.Sleep, + backoff: DefaultBackoff, + } + for _, o := range os { + o.Apply(opts) + } + return opts +} + +type Request struct { + client func(*http.Request) (*http.Response, error) + r *http.Request + o *Options + attempts int + done bool + delay time.Duration +} + +func NewRequest(r *http.Request, client func(*http.Request) (*http.Response, error), o *Options) *Request { + return &Request{ + client: client, + r: r, + o: o, + } +} + +// Done indicates whether or not the request can be attempted any more times. +// +// Initially Done will be false. It will move to true when the following +// occurs: +// +// 1. Do returns a 2xx or 3xx response +// 2. Do returns an error +// 3. The number of attempts exceeds MaxRetries +// 4. No RetryStrategy was returned or only NoRetry, and RetryAfter() had no +// delay. +// +// If Done returns true, Do must never be called again, otherwise Do will +// return ErrorNoMoreAttempts. +// +// If Done returns false, Do needs to be called. +// +// If Do has never been called, this method will always return false. +func (r *Request) Done() bool { + return r.done || r.attempts > r.o.maxRetries +} + +func (r *Request) onError(err error) (*http.Response, error) { + r.done = true + return nil, err +} + +func (r *Request) onDone(resp *http.Response, err error) (*http.Response, error) { + r.done = true + return resp, err +} + +func (r *Request) Do() (*http.Response, error) { + if r.Done() { + // Already done, so don't attempt any more. + return nil, ErrorNoMoreAttempts + } + if r.attempts > 0 { + // This is a retry! + if r.delay > 0 { + // Wait if we have a delay + r.o.sleep(r.delay) + } + // Update the delay + r.delay = r.o.backoff(r.delay) + } + // Bump the number of attempts + r.attempts++ + + // Issue the request + resp, err := r.client(r.r) + if err != nil { + // Return the response and the error if the client returned an error + // TODO: pass err to the strategy funcs. + return r.onDone(resp, err) + } + + // Immediate success if the request is 2xx or 3xx + if http.StatusOK <= resp.StatusCode && resp.StatusCode < http.StatusBadRequest { + return r.onDone(resp, err) + } + + if r.o.retryAfter != nil { + // Check if the Retry-After header is set + d := r.o.retryAfter(resp) + if d != 0 { + // We have the Retry-After header so set the delay and return + r.delay = d + return resp, err + } + } + + // Check each of the retryStrategyFuncs to see if we should retry + s := NoRetry + var errS error + for _, fn := range r.o.retryStrategyFuncs { + s, errS = fn(resp) + if errS != nil { + return r.onError(errS) + } + if s != NoRetry { + // We found a strategy that required a retry + // TODO: we may want to find the retry needing the longest delay + break + } + } + if s == NoRetry { + return r.onDone(resp, err) + } + // Only apply the strategy on the first iteration + if r.attempts == 1 && s == RetryWithInitialDelay { + r.delay = r.o.initialDelay + } + + return resp, err +} + +func NewRoundTripper(inner http.RoundTripper, o ...Option) http.RoundTripper { + return &roundTripper{ + inner: inner, + o: MakeOptions(o...), + } +} + +type roundTripper struct { + inner http.RoundTripper + o *Options +} + +func (rt *roundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + var resp *http.Response + var err error + rr := NewRequest(r, rt.inner.RoundTrip, rt.o) + for !rr.Done() { + resp, err = rr.Do() + } + return resp, err +} diff --git a/internal/retry/request_test.go b/internal/retry/request_test.go new file mode 100644 index 00000000..ad36031f --- /dev/null +++ b/internal/retry/request_test.go @@ -0,0 +1,143 @@ +package retry + +import ( + "fmt" + "io/ioutil" + "net/http" + "strings" + "testing" + "time" +) + +func TestInit_NotDone(t *testing.T) { + req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader("")), + }, nil + }, MakeOptions()) + + if req.Done() { + t.Fatalf("Done() == true; want false") + } +} + +func Test200NoRetryStrategyFunc(t *testing.T) { + req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader("")), + }, nil + }, MakeOptions()) + resp, err := req.Do() + + if !req.Done() { + t.Fatalf("Done() == false; want true") + } + if err != nil { + t.Fatalf("Do() returned err %v; want no err", err) + } + if resp.StatusCode != http.StatusOK { + t.Fatalf("Do() return response with status == %d; want %d", resp.StatusCode, http.StatusOK) + } +} + +func TestDoAfterDoneReturnsError(t *testing.T) { + req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: ioutil.NopCloser(strings.NewReader("")), + }, nil + }, MakeOptions()) + + // This Do() is successful + req.Do() + + // This Do() returns an error. + resp, err := req.Do() + if err != ErrorNoMoreAttempts { + t.Fatalf("Do() returned err %v; want %v", err, ErrorNoMoreAttempts) + } + if resp != nil { + t.Fatalf("Do() returned a response; want nil") + } +} + +func Test2xx3xxAlwaysDone(t *testing.T) { + for code := http.StatusOK; code < http.StatusBadRequest; code++ { + t.Run(fmt.Sprintf("status %d", code), func(t *testing.T) { + req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: code, + Body: ioutil.NopCloser(strings.NewReader("")), + }, nil + }, MakeOptions(Strategy(func(_ *http.Response) (RetryStrategy, error) { + // Always force a retry if the strategy is called. + return RetryImmediate, nil + }))) + req.Do() + if !req.Done() { + t.Fatalf("Done() == false; want true") + } + }) + } +} + +func TestRetryAfterZeroDuration(t *testing.T) { + req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusBadRequest, + Body: ioutil.NopCloser(strings.NewReader("")), + }, nil + }, MakeOptions(RetryAfter(func(_ *http.Response) time.Duration { + return 0 + }))) + req.Do() + if !req.Done() { + t.Fatalf("Done() == false; want true") + } +} + +func TestRetryAfterDuration(t *testing.T) { + slept := time.Duration(0) + opts := MakeOptions(RetryAfter(func(_ *http.Response) time.Duration { + return time.Minute + })) + opts.sleep = func(d time.Duration) { + slept += d + } + req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusBadRequest, + Body: ioutil.NopCloser(strings.NewReader("")), + }, nil + }, opts) + req.Do() + if req.Done() { + t.Fatalf("Done() == true; want false") + } + + req.Do() + if req.Done() { + t.Fatalf("Done() == true; want false") + } + if slept != time.Minute { + t.Fatalf("Only slept for %d; want sleep for %d", slept, time.Minute) + } +} + +func TestZeroMaxRetriesOnlyTriesOnce(t *testing.T) { + req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusBadRequest, + Body: ioutil.NopCloser(strings.NewReader("")), + }, nil + }, MakeOptions(MaxRetries(0), RetryAfter(func(_ *http.Response) time.Duration { + // Force a retry + return time.Minute + }))) + req.Do() + if !req.Done() { + t.Fatalf("Done() == false; want true") + } +} From 24c936e1f30201f54c86fd6d809c795251d7131b Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 6 Jun 2022 11:32:04 +1000 Subject: [PATCH 065/172] Add retry logic for github errors to improve reliability. (#127) --- cmd/collect_signals/main.go | 2 +- internal/githubapi/roundtripper.go | 134 ++++++++++ internal/githubapi/roundtripper_test.go | 323 ++++++++++++++++++++++++ 3 files changed, 458 insertions(+), 1 deletion(-) create mode 100644 internal/githubapi/roundtripper.go create mode 100644 internal/githubapi/roundtripper_test.go diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 5f809025..f8b99969 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -149,7 +149,7 @@ func main() { http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = *workersFlag * 5 // Prepare a client for communicating with GitHub's GraphQLv4 API and Restv3 API - rt := roundtripper.NewTransport(ctx, scLogger) + rt := githubapi.NewRoundTripper(roundtripper.NewTransport(ctx, scLogger), logger) httpClient := &http.Client{ Transport: rt, } diff --git a/internal/githubapi/roundtripper.go b/internal/githubapi/roundtripper.go new file mode 100644 index 00000000..f1b1972c --- /dev/null +++ b/internal/githubapi/roundtripper.go @@ -0,0 +1,134 @@ +package githubapi + +import ( + "bytes" + "encoding/json" + "io/ioutil" + "net/http" + "regexp" + "strconv" + "strings" + "time" + + "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/internal/retry" + log "github.com/sirupsen/logrus" +) + +const ( + githubErrorIdSearch = "\"error_500\"" +) + +var ( + issueCommentsRe = regexp.MustCompile("^repos/[^/]+/[^/]+/issues/comments$") +) + +func NewRoundTripper(rt http.RoundTripper, logger *log.Logger) http.RoundTripper { + s := &strategies{logger: logger} + return retry.NewRoundTripper(rt, + retry.InitialDelay(2*time.Minute), + retry.RetryAfter(s.RetryAfter), + retry.Strategy(s.SecondaryRateLimit), + retry.Strategy(s.ServerError400), + retry.Strategy(s.ServerError), + ) +} + +type strategies struct { + logger *log.Logger +} + +func respBodyContains(r *http.Response, search string) (bool, error) { + data, err := ioutil.ReadAll(r.Body) + defer r.Body.Close() + r.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + if err != nil { + return false, err + } + return bytes.Contains(data, []byte(search)), nil +} + +// ServerError implements retry.RetryStrategyFn +func (s *strategies) ServerError(r *http.Response) (retry.RetryStrategy, error) { + if r.StatusCode < 500 || 600 <= r.StatusCode { + return retry.NoRetry, nil + } + s.logger.WithField("status", r.Status).Warn("5xx: detected") + if issueCommentsRe.MatchString(strings.Trim(r.Request.URL.Path, "/")) { + s.logger.Warn("Ignoring /repos/X/Y/issues/comments url.") + // If the req url was /repos/[owner]/[name]/issues/comments pass the + // error through as it is likely a GitHub bug. + return retry.NoRetry, nil + } + return retry.RetryImmediate, nil + +} + +// ServerError400 implements retry.RetryStrategyFn +func (s *strategies) ServerError400(r *http.Response) (retry.RetryStrategy, error) { + if r.StatusCode != http.StatusBadRequest { + return retry.NoRetry, nil + } + s.logger.Warn("400: bad request detected") + if r.Header.Get("Content-Type") != "text/html" { + return retry.NoRetry, nil + } + s.logger.Debug("It's a text/html doc") + if isError, err := respBodyContains(r, githubErrorIdSearch); isError { + s.logger.Debug("Found target string - assuming 500.") + return retry.RetryImmediate, nil + } else { + return retry.NoRetry, err + } +} + +// SecondaryRateLimit implements retry.RetryStrategyFn +func (s *strategies) SecondaryRateLimit(r *http.Response) (retry.RetryStrategy, error) { + if r.StatusCode != http.StatusForbidden { + return retry.NoRetry, nil + } + s.logger.Warn("403: forbidden detected") + errorResponse := &github.ErrorResponse{Response: r} + data, err := ioutil.ReadAll(r.Body) + r.Body.Close() + r.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + if err != nil || data == nil { + s.logger.WithFields( + log.Fields{ + "error": err, + "data_nil": (data == nil), + }).Warn("ReadAll failed.") + return retry.NoRetry, err + } + // Don't error check the unmarshall - if there is an error and the parsing + // has failed then this function will return with no retry. A parsing error + // here would mean the server did something wrong. Not attempting a retry + // will cause the response to be processed again by go-github with an error + // being generated there. + json.Unmarshal(data, errorResponse) + s.logger.WithFields(log.Fields{ + "url": errorResponse.DocumentationURL, + "message": errorResponse.Message, + }).Warn("Error response data") + if strings.HasSuffix(errorResponse.DocumentationURL, "#abuse-rate-limits") || + strings.HasSuffix(errorResponse.DocumentationURL, "#secondary-rate-limits") { + s.logger.Warn("Secondary rate limit hit.") + return retry.RetryWithInitialDelay, nil + } + s.logger.Warn("Not an abuse rate limit error.") + return retry.NoRetry, nil +} + +// RetryAfter implements retry.RetryAfterFn +// TODO: move to retry once we're confident it is working. +func (s *strategies) RetryAfter(r *http.Response) time.Duration { + if v := r.Header["Retry-After"]; len(v) > 0 { + s.logger.Warn("Detected Retry-After header.") + // According to GitHub support, the "Retry-After" header value will be + // an integer which represents the number of seconds that one should + // wait before resuming making requests. + retryAfterSeconds, _ := strconv.ParseInt(v[0], 10, 64) // Error handling is noop. + return time.Duration(retryAfterSeconds) * time.Second + } + return 0 +} diff --git a/internal/githubapi/roundtripper_test.go b/internal/githubapi/roundtripper_test.go new file mode 100644 index 00000000..51f14a18 --- /dev/null +++ b/internal/githubapi/roundtripper_test.go @@ -0,0 +1,323 @@ +package githubapi + +import ( + "bytes" + "errors" + "fmt" + "io/ioutil" + "net/http" + "net/url" + "testing" + "time" + + "github.com/ossf/criticality_score/internal/retry" + log "github.com/sirupsen/logrus" +) + +const ( + testAbuseRateLimitDocUrl = "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" + testSecondaryRateLimitDocUrl = "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits" +) + +func newTestStrategies() *strategies { + logger := log.New() + logger.Out = ioutil.Discard + return &strategies{logger: logger} +} + +type readerFn func(p []byte) (n int, err error) + +// Read implements the io.Reader interface +func (r readerFn) Read(p []byte) (n int, err error) { + return r(p) +} + +func TestRetryAfter(t *testing.T) { + r := &http.Response{Header: http.Header{http.CanonicalHeaderKey("Retry-After"): {"123"}}} + if d := newTestStrategies().RetryAfter(r); d != 123*time.Second { + t.Fatalf("RetryAfter() == %d, want %v", d, 123*time.Second) + } +} + +func TestRetryAfter_NoHeader(t *testing.T) { + if d := newTestStrategies().RetryAfter(&http.Response{}); d != 0 { + t.Fatalf("RetryAfter() == %d, want 0", d) + } +} + +func TestRetryAfter_InvalidTime(t *testing.T) { + r := &http.Response{Header: http.Header{http.CanonicalHeaderKey("Retry-After"): {"junk"}}} + if d := newTestStrategies().RetryAfter(r); d != 0 { + t.Fatalf("RetryAfter() == %d, want 0", d) + } +} + +func TestRetryAfter_ZeroTime(t *testing.T) { + r := &http.Response{Header: http.Header{http.CanonicalHeaderKey("Retry-After"): {"0"}}} + if d := newTestStrategies().RetryAfter(r); d != 0 { + t.Fatalf("RetryAfter() == %d, want 0", d) + } +} + +func TestServerError(t *testing.T) { + u, _ := url.Parse("https://api.github.com/repos/example/example") + r := &http.Response{ + Request: &http.Request{URL: u}, + StatusCode: http.StatusInternalServerError, + } + s, err := newTestStrategies().ServerError(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != retry.RetryImmediate { + t.Fatalf("ServerError() == %v, want %v", s, retry.RetryImmediate) + } +} + +func TestServerError_IssueComments(t *testing.T) { + u, _ := url.Parse("https://api.github.com/repos/example/example/issues/comments/") + r := &http.Response{ + Request: &http.Request{URL: u}, + StatusCode: http.StatusInternalServerError, + } + s, err := newTestStrategies().ServerError(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != retry.NoRetry { + t.Fatalf("ServerError() == %v, want %v", s, retry.NoRetry) + } +} + +func TestServerError_StatusCodes(t *testing.T) { + tests := []struct { + statusCode int + strategy retry.RetryStrategy + }{ + {statusCode: http.StatusOK, strategy: retry.NoRetry}, + {statusCode: http.StatusCreated, strategy: retry.NoRetry}, + {statusCode: http.StatusPermanentRedirect, strategy: retry.NoRetry}, + {statusCode: http.StatusFound, strategy: retry.NoRetry}, + {statusCode: http.StatusBadRequest, strategy: retry.NoRetry}, + {statusCode: http.StatusConflict, strategy: retry.NoRetry}, + {statusCode: http.StatusFailedDependency, strategy: retry.NoRetry}, + {statusCode: http.StatusGone, strategy: retry.NoRetry}, + {statusCode: http.StatusInternalServerError, strategy: retry.RetryImmediate}, + {statusCode: http.StatusNotImplemented, strategy: retry.RetryImmediate}, + {statusCode: http.StatusBadGateway, strategy: retry.RetryImmediate}, + {statusCode: http.StatusServiceUnavailable, strategy: retry.RetryImmediate}, + {statusCode: http.StatusGatewayTimeout, strategy: retry.RetryImmediate}, + } + for _, test := range tests { + t.Run(fmt.Sprintf("status %d", test.statusCode), func(t *testing.T) { + u, _ := url.Parse("https://api.github.com/repos/example/example") + r := &http.Response{ + Request: &http.Request{URL: u}, + StatusCode: test.statusCode, + } + s, _ := newTestStrategies().ServerError(r) + if s != test.strategy { + t.Fatalf("ServerError() == %v, want %v", s, test.strategy) + } + }) + } +} + +func TestServerError400(t *testing.T) { + r := &http.Response{ + Header: http.Header{http.CanonicalHeaderKey("Content-Type"): {"text/html"}}, + StatusCode: http.StatusBadRequest, + Body: ioutil.NopCloser(bytes.NewBuffer([]byte(`This is an error`))), + } + s, err := newTestStrategies().ServerError400(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != retry.RetryImmediate { + t.Fatalf("ServerError() == %v, want %v", s, retry.RetryImmediate) + } +} + +func TestServerError400_NoMatchingString(t *testing.T) { + r := &http.Response{ + Header: http.Header{http.CanonicalHeaderKey("Content-Type"): {"text/html"}}, + StatusCode: http.StatusBadRequest, + Body: ioutil.NopCloser(bytes.NewBuffer([]byte(`Web PageThis is an error`))), + } + s, err := newTestStrategies().ServerError400(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != test.strategy { + t.Fatalf("ServerError() == %v, want %v", s, test.strategy) + } + }) + } +} + +func TestSecondaryRateLimit(t *testing.T) { + r := &http.Response{ + StatusCode: http.StatusForbidden, + Body: ioutil.NopCloser(bytes.NewBuffer( + []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocUrl)))), + } + s, err := newTestStrategies().SecondaryRateLimit(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != retry.RetryWithInitialDelay { + t.Fatalf("ServerError() == %v, want %v", s, retry.RetryWithInitialDelay) + } +} + +func TestSecondaryRateLimit_AbuseUrl(t *testing.T) { + r := &http.Response{ + StatusCode: http.StatusForbidden, + Body: ioutil.NopCloser(bytes.NewBuffer( + []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testAbuseRateLimitDocUrl)))), + } + s, err := newTestStrategies().SecondaryRateLimit(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != retry.RetryWithInitialDelay { + t.Fatalf("ServerError() == %v, want %v", s, retry.RetryWithInitialDelay) + } +} + +func TestSecondaryRateLimit_OtherUrl(t *testing.T) { + r := &http.Response{ + StatusCode: http.StatusForbidden, + Body: ioutil.NopCloser(bytes.NewBuffer([]byte(`{"message": "test", "documentation_url": "https://example.org/"}`))), + } + s, err := newTestStrategies().SecondaryRateLimit(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != retry.NoRetry { + t.Fatalf("ServerError() == %v, want %v", s, retry.NoRetry) + } +} + +func TestSecondaryRateLimit_BodyError(t *testing.T) { + want := errors.New("test error") + r := &http.Response{ + StatusCode: http.StatusForbidden, + Body: ioutil.NopCloser(readerFn(func(b []byte) (int, error) { + return 0, want + })), + } + _, err := newTestStrategies().SecondaryRateLimit(r) + if err == nil { + t.Fatalf("ServerError() returned no error, want %v", want) + } + if err != want { + t.Fatalf("ServerError() errored %v, want %v", err, want) + } +} + +func TestSecondaryRateLimit_StatusCodes(t *testing.T) { + tests := []struct { + statusCode int + strategy retry.RetryStrategy + }{ + {statusCode: http.StatusOK, strategy: retry.NoRetry}, + {statusCode: http.StatusCreated, strategy: retry.NoRetry}, + {statusCode: http.StatusPermanentRedirect, strategy: retry.NoRetry}, + {statusCode: http.StatusFound, strategy: retry.NoRetry}, + {statusCode: http.StatusBadRequest, strategy: retry.NoRetry}, + {statusCode: http.StatusForbidden, strategy: retry.RetryWithInitialDelay}, + {statusCode: http.StatusConflict, strategy: retry.NoRetry}, + {statusCode: http.StatusFailedDependency, strategy: retry.NoRetry}, + {statusCode: http.StatusGone, strategy: retry.NoRetry}, + {statusCode: http.StatusInternalServerError, strategy: retry.NoRetry}, + {statusCode: http.StatusNotImplemented, strategy: retry.NoRetry}, + {statusCode: http.StatusBadGateway, strategy: retry.NoRetry}, + {statusCode: http.StatusServiceUnavailable, strategy: retry.NoRetry}, + {statusCode: http.StatusGatewayTimeout, strategy: retry.NoRetry}, + } + for _, test := range tests { + t.Run(fmt.Sprintf("status %d", test.statusCode), func(t *testing.T) { + r := &http.Response{ + StatusCode: test.statusCode, + Body: ioutil.NopCloser(bytes.NewBuffer( + []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocUrl)))), + } + s, err := newTestStrategies().SecondaryRateLimit(r) + if err != nil { + t.Fatalf("ServerError() errored %v, want no error", err) + } + if s != test.strategy { + t.Fatalf("ServerError() == %v, want %v", s, test.strategy) + } + }) + } +} From 19b7a302fe43fe4564f19e3e1ce0b1bd50b0e01e Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 8 Jun 2022 08:14:30 +1000 Subject: [PATCH 066/172] Fix a bug where nil values weren't being marshald correctly. (#128) Also improve the error reporting so it is easy to figure out what went wrong. --- cmd/collect_signals/result/csv.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/cmd/collect_signals/result/csv.go b/cmd/collect_signals/result/csv.go index 1f313a6a..c92d82cc 100644 --- a/cmd/collect_signals/result/csv.go +++ b/cmd/collect_signals/result/csv.go @@ -89,7 +89,7 @@ func (r *csvRecord) WriteSignalSet(s signal.Set) error { data := signal.SetAsMap(s, true) for k, v := range data { if s, err := marshalValue(v); err != nil { - return err + return fmt.Errorf("failed to write field %s: %w", k, err) } else { r.values[k] = s } @@ -107,7 +107,9 @@ func marshalValue(value any) (string, error) { return fmt.Sprintf("%v", value), nil case time.Time: return v.Format(time.RFC3339), nil + case nil: + return "", nil default: - return "", MarshalError + return "", fmt.Errorf("%w: %T", MarshalError, value) } } From 3446d7c63d9402e19f2fba185bfd338f036c21f4 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 10 Jun 2022 16:19:59 +1000 Subject: [PATCH 067/172] Add deps.dev support to the signal collector. (#129) --- cmd/collect_signals/depsdev/bq.go | 117 +++++ cmd/collect_signals/depsdev/collector.go | 90 ++++ cmd/collect_signals/depsdev/dependents.go | 164 +++++++ cmd/collect_signals/main.go | 24 +- go.mod | 16 + go.sum | 519 +++++++++++++++++++++- 6 files changed, 927 insertions(+), 3 deletions(-) create mode 100644 cmd/collect_signals/depsdev/bq.go create mode 100644 cmd/collect_signals/depsdev/collector.go create mode 100644 cmd/collect_signals/depsdev/dependents.go diff --git a/cmd/collect_signals/depsdev/bq.go b/cmd/collect_signals/depsdev/bq.go new file mode 100644 index 00000000..2c15dcab --- /dev/null +++ b/cmd/collect_signals/depsdev/bq.go @@ -0,0 +1,117 @@ +package depsdev + +import ( + "context" + "errors" + + "cloud.google.com/go/bigquery" + "google.golang.org/api/googleapi" + "google.golang.org/api/iterator" +) + +var NoResultError = errors.New("no results returned") + +type Dataset struct { + ds *bigquery.Dataset +} + +type Table struct { + md *bigquery.TableMetadata +} + +// bqAPI wraps the BigQuery Go API to make the deps.dev implementation easier to unit test. +type bqAPI interface { + Project() string + OneResultQuery(ctx context.Context, query string, params map[string]any, result any) error + NoResultQuery(ctx context.Context, query string, params map[string]any) error + GetDataset(ctx context.Context, id string) (*Dataset, error) + CreateDataset(ctx context.Context, id string) (*Dataset, error) + GetTable(ctx context.Context, d *Dataset, id string) (*Table, error) +} + +type bq struct { + client *bigquery.Client +} + +func (b *bq) Project() string { + return b.client.Project() +} + +func (b *bq) OneResultQuery(ctx context.Context, query string, params map[string]any, result any) error { + q := b.client.Query(query) + it, err := q.Read(ctx) + if err != nil { + return err + } + err = it.Next(result) + if err == iterator.Done { + return NoResultError + } + if err != nil { + return err + } + return nil +} + +func (b *bq) NoResultQuery(ctx context.Context, query string, params map[string]any) error { + q := b.client.Query(query) + for k, v := range params { + q.Parameters = append(q.Parameters, bigquery.QueryParameter{Name: k, Value: v}) + } + j, err := q.Run(ctx) + if err != nil { + return err + } + status, err := j.Wait(ctx) + if err != nil { + return err + } + if err := status.Err(); err != nil { + return err + } + return nil +} + +func (b *bq) GetDataset(ctx context.Context, id string) (*Dataset, error) { + ds := b.client.Dataset(id) + _, err := ds.Metadata(ctx) + if isNotFound(err) { + return nil, nil + } + if err != nil { + return nil, err + } + return &Dataset{ + ds: ds, + }, nil +} + +func (b *bq) CreateDataset(ctx context.Context, id string) (*Dataset, error) { + ds := b.client.Dataset(id) + if err := ds.Create(ctx, &bigquery.DatasetMetadata{}); err != nil { + return nil, err + } + return &Dataset{ + ds: ds, + }, nil +} + +func (b *bq) GetTable(ctx context.Context, d *Dataset, id string) (*Table, error) { + t := d.ds.Table(id) + md, err := t.Metadata(ctx) + if isNotFound(err) { + return nil, nil + } + if err != nil { + return nil, err + } + return &Table{md: md}, nil +} + +func isNotFound(err error) bool { + if err == nil { + return false + } + apiErr, ok := err.(*googleapi.Error) + return ok && apiErr.Code != 404 +} diff --git a/cmd/collect_signals/depsdev/collector.go b/cmd/collect_signals/depsdev/collector.go new file mode 100644 index 00000000..f2bfa88e --- /dev/null +++ b/cmd/collect_signals/depsdev/collector.go @@ -0,0 +1,90 @@ +package depsdev + +import ( + "context" + "net/url" + "strings" + + "cloud.google.com/go/bigquery" + "github.com/ossf/criticality_score/cmd/collect_signals/collector" + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" + "github.com/ossf/criticality_score/cmd/collect_signals/signal" + log "github.com/sirupsen/logrus" +) + +const defaultLocation = "US" + +type depsDevSet struct { + DependentCount signal.Field[int] `signal:"dependent_count"` +} + +func (s *depsDevSet) Namespace() signal.Namespace { + return signal.Namespace("depsdev") +} + +type depsDevCollector struct { + logger *log.Logger + dependents *dependents +} + +func (c *depsDevCollector) EmptySet() signal.Set { + return &depsDevSet{} +} + +func (c *depsDevCollector) IsSupported(r projectrepo.Repo) bool { + _, t := parseRepoURL(r.URL()) + return t != "" +} + +func (c *depsDevCollector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { + var s depsDevSet + n, t := parseRepoURL(r.URL()) + if t == "" { + return &s, nil + } + c.logger.WithField("url", r.URL().String()).Debug("Fetching deps.dev dependent count") + deps, found, err := c.dependents.Count(ctx, n, t) + if err != nil { + return nil, err + } + if found { + s.DependentCount.Set(deps) + } + return &s, nil +} + +// NewCollector creates a new Collector for gathering data from deps.dev. +// +// TODO add options to configure the dataset: +// - an optional projectID +// - datasetname +// - when to expire the dataset (maybe?) +// - force dataset re-creation (-update-strategy = always,stale,weekly,monthly,never) +// - force dataset destruction (-depsdev-destroy-data) +func NewCollector(ctx context.Context, logger *log.Logger, projectID string) (collector.Collector, error) { + gcpClient, err := bigquery.NewClient(ctx, projectID) + if err != nil { + return nil, err + } + // Set the location + gcpClient.Location = defaultLocation + + dependents, err := NewDependents(ctx, gcpClient, logger) + if err != nil { + return nil, err + } + + return &depsDevCollector{ + logger: logger, + dependents: dependents, + }, nil +} + +func parseRepoURL(u *url.URL) (projectName, projectType string) { + switch hn := u.Hostname(); hn { + case "github.com": + return strings.Trim(u.Path, "/"), "GITHUB" + default: + return "", "" + } +} diff --git a/cmd/collect_signals/depsdev/dependents.go b/cmd/collect_signals/depsdev/dependents.go new file mode 100644 index 00000000..1ff81972 --- /dev/null +++ b/cmd/collect_signals/depsdev/dependents.go @@ -0,0 +1,164 @@ +package depsdev + +import ( + "bytes" + "context" + "errors" + "text/template" + "time" + + "cloud.google.com/go/bigquery" + log "github.com/sirupsen/logrus" + _ "google.golang.org/api/bigquery/v2" +) + +const ( + datasetName = "depsdev_analysis" + dependentCountsTableName = "dependent_counts" + packageVersionToProjectTableName = "package_version_to_project" + + snapshotQuery = "SELECT MAX(Time) AS SnapshotTime FROM `bigquery-public-data.deps_dev_v1.Snapshots`" +) + +// TODO: prune root dependents that come from the same project. +// TODO: count "# packages per project" to determine dependent ratio + +const dataQuery = ` +CREATE TEMP TABLE rawDependentCounts(Name STRING, Version STRING, System STRING, DependentCount INT) +AS + SELECT d.Dependency.Name as Name, d.Dependency.Version as Version, d.Dependency.System as System, COUNT(1) AS DependentCount + FROM ` + "`bigquery-public-data.deps_dev_v1.Dependencies`" + `AS d + JOIN (SELECT System, Name, Version, ROW_NUMBER() OVER (PARTITION BY Name ORDER BY VersionInfo.Ordinal Desc) AS RowNumber + FROM ` + "`bigquery-public-data.deps_dev_v1.PackageVersions`" + ` + WHERE SnapshotAt = @part) AS lv ON (lv.RowNumber = 1 AND lv.Name = d.Name AND lv.Version = d.Version AND lv.System = d.System) + WHERE d.SnapshotAt = @part + GROUP BY Name, Version, System; + +CREATE TABLE ` + "`{{.ProjectID}}.{{.DatasetName}}.{{.TableName}}`" + ` +AS +WITH pvp AS ( + SELECT System, Name, Version, ProjectName, ProjectType + FROM ` + "`bigquery-public-data.deps_dev_v1.PackageVersionToProject`" + ` + WHERE SnapshotAt = @part +) +SELECT pvp.ProjectName AS ProjectName, pvp.ProjectType AS ProjectType, SUM(d.DependentCount) AS DependentCount + FROM pvp + JOIN rawDependentCounts AS d + ON (pvp.System = d.System AND pvp.Name = d.Name AND pvp.Version = d.Version) +GROUP BY ProjectName, ProjectType; +` + +const countQuery = ` +SELECT DependentCount +FROM ` + "`{{.ProjectID}}.{{.DatasetName}}.{{.TableName}}`" + ` +WHERE ProjectName = @projectname AND ProjectType = @projecttype; +` + +func NewDependents(ctx context.Context, client *bigquery.Client, logger *log.Logger) (*dependents, error) { + c := &dependents{ + b: &bq{client: client}, + logger: logger, + } + var err error + + // Populate the snapshot time + c.snapshotTime, err = c.getLatestSnapshotTime(ctx) + if err != nil { + return nil, err + } + + // Ensure the dataset exists + ds, err := c.getOrCreateDataset(ctx) + if err != nil { + return nil, err + } + + // Ensure the dependent count table exists and is populated + t, err := c.b.GetTable(ctx, ds, dependentCountsTableName) + if err != nil { + return nil, err + } + if t != nil { + c.logger.Warn("dependent count table exists") + } else { + c.logger.Warn("creating dependent count table") + err := c.b.NoResultQuery(ctx, c.generateQuery(dataQuery), map[string]any{"part": c.snapshotTime}) + if err != nil { + return nil, err + } + } + + // Cache the data query to avoid re-generating it repeatedly. + c.countQuery = c.generateQuery(countQuery) + + return c, nil +} + +type dependents struct { + b bqAPI + logger *log.Logger + snapshotTime time.Time + countQuery string +} + +func (c *dependents) generateQuery(temp string) string { + t := template.Must(template.New("query").Parse(temp)) + var b bytes.Buffer + t.Execute(&b, struct { + ProjectID string + DatasetName string + TableName string + }{c.b.Project(), datasetName, dependentCountsTableName}) + return b.String() +} + +func (c *dependents) Count(ctx context.Context, projectName, projectType string) (int, bool, error) { + var rec struct { + DependentCount int + } + params := map[string]any{ + "projectname": projectName, + "projecttype": projectType, + } + err := c.b.OneResultQuery(ctx, c.countQuery, params, &rec) + if err == nil { + return rec.DependentCount, true, nil + } + if errors.Is(err, NoResultError) { + return 0, false, nil + } + return 0, false, err +} + +func (c *dependents) LatestSnapshotTime() time.Time { + return c.snapshotTime +} + +func (c *dependents) getLatestSnapshotTime(ctx context.Context) (time.Time, error) { + var rec struct { + SnapshotTime time.Time + } + if err := c.b.OneResultQuery(ctx, snapshotQuery, nil, &rec); err != nil { + return time.Time{}, err + } + return rec.SnapshotTime, nil +} + +func (c *dependents) getOrCreateDataset(ctx context.Context) (*Dataset, error) { + // Attempt to get the current dataset + ds, err := c.b.GetDataset(ctx, datasetName) + if err != nil { + return nil, err + } + if ds == nil { + // Dataset doesn't exist so create it + c.logger.Debug("creating dependent count dataset") + ds, err = c.b.CreateDataset(ctx, datasetName) + if err != nil { + return nil, err + } + } else { + c.logger.Debug("dependent count dataset exists") + } + return ds, nil +} diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index f8b99969..66da6978 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -13,6 +13,7 @@ import ( "strings" "github.com/ossf/criticality_score/cmd/collect_signals/collector" + "github.com/ossf/criticality_score/cmd/collect_signals/depsdev" "github.com/ossf/criticality_score/cmd/collect_signals/github" "github.com/ossf/criticality_score/cmd/collect_signals/githubmentions" "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" @@ -29,8 +30,9 @@ import ( const defaultLogLevel = log.InfoLevel var ( - workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") - logFlag = logflag.Level(defaultLogLevel) + gcpProjectFlag = flag.String("gcp-project", "", "the Google Cloud Project to use. Required for deps.dev data collection.") + workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") + logFlag = logflag.Level(defaultLogLevel) ) func init() { @@ -163,6 +165,24 @@ func main() { collector.Register(&github.IssuesCollector{}) collector.Register(githubmentions.NewCollector(ghClient)) + // Register the deps.dev collector IFF there is a GCP Project ID set. + if *gcpProjectFlag == "" { + logger.Warn("No GCP Project ID set. Skipping deps.dev signal collection") + } else { + ddcollector, err := depsdev.NewCollector(ctx, logger, *gcpProjectFlag) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "gcp_project_id": *gcpProjectFlag, + }).Error("Failed to create deps.dev collector") + os.Exit(2) + } + logger.WithFields(log.Fields{ + "gcp_project_id": *gcpProjectFlag, + }).Info("deps.dev signal collector enabled") + collector.Register(ddcollector) + } + // Prepare the output writer out := result.NewCsvWriter(w, collector.EmptySets()) diff --git a/go.mod b/go.mod index 8060cb71..62a0118a 100644 --- a/go.mod +++ b/go.mod @@ -3,25 +3,41 @@ module github.com/ossf/criticality_score go 1.18 require ( + cloud.google.com/go/bigquery v1.32.0 github.com/google/go-github/v44 v44.1.0 github.com/iancoleman/strcase v0.2.0 github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 github.com/sirupsen/logrus v1.8.1 + google.golang.org/api v0.74.0 + gopkg.in/yaml.v3 v3.0.1 ) require ( + cloud.google.com/go v0.100.2 // indirect + cloud.google.com/go/compute v1.5.0 // indirect + cloud.google.com/go/iam v0.3.0 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/google/go-cmp v0.5.8 // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/googleapis/gax-go/v2 v2.3.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect github.com/stretchr/testify v1.7.1 // indirect go.opencensus.io v0.23.0 // indirect golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect golang.org/x/net v0.0.0-20220401154927-543a649e0bdd // indirect + golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9 // indirect + google.golang.org/grpc v1.45.0 // indirect + google.golang.org/protobuf v1.28.0 // indirect ) diff --git a/go.sum b/go.sum index 5d82bd4f..eb60af09 100644 --- a/go.sum +++ b/go.sum @@ -1,12 +1,86 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= +cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= +cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= +cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/bigquery v1.32.0 h1:0OMQYCp03Ff9B5OeVY8GGUlOC99s93bjM+c5xS0H5gs= +cloud.google.com/go/bigquery v1.32.0/go.mod h1:hAfV1647X+/fGUqeVVdKW+HfYtT5UCjOZsuOydOSH4M= +cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= +cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= +cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/datacatalog v1.3.0 h1:3llKXv7cC1acsWjvWmG0NQQkYVSVgunMSfVk7h6zz8Q= +cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= +cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.22.0 h1:NUV0NNp9nkBuW66BFRLuMgldN60C57ET3dhbwLIYio8= +cloud.google.com/go/storage v1.22.0/go.mod h1:GbaLEoMqbVm6sx3Z0R++gSiBlgMv6yUi2q1DeGFKQgE= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 h1:tXKVfhE7FcSkhkv0UwkLvPDeZ4kz6OXd0PKPlFqf81M= github.com/bradleyfalzon/ghinstallation/v2 v2.0.4/go.mod h1:B40qPqJxWE0jDZgOR1JmaMy+4AY1eBP+IByOvqyAKp0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI= +github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= @@ -14,7 +88,16 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= +github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -22,121 +105,536 @@ github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzw github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= github.com/google/go-github/v44 v44.1.0 h1:shWPaufgdhr+Ad4eo/pZv9ORTxFpsxPEPEuuXAKIQGA= github.com/google/go-github/v44 v44.1.0/go.mod h1:iWn00mWcP6PRWHhXm0zuFJ8wbEjE5AGO5D5HXYM4zgw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= +github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0 h1:nRJtk3y8Fm770D42QV6T90ZnvFZyk7agSo3Q+Z9p3WI= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 h1:Db6m7J/xaItRxVbesKIXwngw+Tr1IERv/LCnRBzhHvk= github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4/go.mod h1:PbooSR+65A6HA+eoJ7ICwek/muANHZsR08QV24tuiKA= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 h1:82EIpiGB79OIPgSGa63Oj4Ipf+YAX1c6A9qjmEYoRXc= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220401154927-543a649e0bdd h1:zYlwaUHTmxuf6H7hwO2dgwqozQmH7zf4x+/qql4oVWc= golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= +golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= +google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= +google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= +google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= +google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= +google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9 h1:XGQ6tc+EnM35IAazg4y6AHmUg4oK8NXsXaILte1vRlk= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= +google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -145,13 +643,32 @@ google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzi google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From ddc5df925b3a1d332bbdb860cb37f0a1732a8a71 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 16 Jun 2022 13:03:59 +1000 Subject: [PATCH 068/172] Initial import of a scorer command for scoring a csv file of signals. (#131) * Initial import of a scorer command for scoring a csv file of signals. - loads a YAML config file that defines the fields, weights, bounds, etc. - scores each row of signals as generated by `collect_signals`, adding the result to a new column - sorts the records and outputs it as a CSV --- cmd/scorer/algorithm/algorithm.go | 7 + cmd/scorer/algorithm/distribution.go | 37 +++++ cmd/scorer/algorithm/input.go | 54 +++++++ cmd/scorer/algorithm/registry.go | 53 ++++++ cmd/scorer/algorithm/value.go | 61 +++++++ cmd/scorer/algorithm/wam/wam.go | 38 +++++ cmd/scorer/config.go | 127 +++++++++++++++ cmd/scorer/main.go | 231 +++++++++++++++++++++++++++ cmd/scorer/pq.go | 66 ++++++++ config/scorer/original_pike.yml | 65 ++++++++ config/scorer/pike_depsdev.yml | 84 ++++++++++ 11 files changed, 823 insertions(+) create mode 100644 cmd/scorer/algorithm/algorithm.go create mode 100644 cmd/scorer/algorithm/distribution.go create mode 100644 cmd/scorer/algorithm/input.go create mode 100644 cmd/scorer/algorithm/registry.go create mode 100644 cmd/scorer/algorithm/value.go create mode 100644 cmd/scorer/algorithm/wam/wam.go create mode 100644 cmd/scorer/config.go create mode 100644 cmd/scorer/main.go create mode 100644 cmd/scorer/pq.go create mode 100644 config/scorer/original_pike.yml create mode 100644 config/scorer/pike_depsdev.yml diff --git a/cmd/scorer/algorithm/algorithm.go b/cmd/scorer/algorithm/algorithm.go new file mode 100644 index 00000000..4f0fb717 --- /dev/null +++ b/cmd/scorer/algorithm/algorithm.go @@ -0,0 +1,7 @@ +package algorithm + +type Algorithm interface { + Score(record map[string]float64) float64 +} + +type Factory func(inputs []*Input) (Algorithm, error) diff --git a/cmd/scorer/algorithm/distribution.go b/cmd/scorer/algorithm/distribution.go new file mode 100644 index 00000000..5ce71b87 --- /dev/null +++ b/cmd/scorer/algorithm/distribution.go @@ -0,0 +1,37 @@ +package algorithm + +import ( + "math" +) + +type Distribution struct { + name string + normalizeFn func(float64) float64 +} + +func (d *Distribution) String() string { + return d.name +} + +func (d *Distribution) Normalize(v float64) float64 { + return d.normalizeFn(v) +} + +var ( + normalizationFuncs = map[string]func(float64) float64{ + "linear": func(v float64) float64 { return v }, + "zapfian": func(v float64) float64 { return math.Log(1 + v) }, + } + DefaultDistributionName = "linear" +) + +func LookupDistribution(name string) *Distribution { + fn, ok := normalizationFuncs[name] + if !ok { + return nil + } + return &Distribution{ + name: name, + normalizeFn: fn, + } +} diff --git a/cmd/scorer/algorithm/input.go b/cmd/scorer/algorithm/input.go new file mode 100644 index 00000000..0586aa4e --- /dev/null +++ b/cmd/scorer/algorithm/input.go @@ -0,0 +1,54 @@ +package algorithm + +type Bounds struct { + Lower float64 `yaml:"lower"` + Upper float64 `yaml:"upper"` + SmallerIsBetter bool `yaml:"smaller_is_better"` +} + +func (b Bounds) Apply(v float64) float64 { + // |----L---v----U----| == v stays as is + // |--v-L--------U----| == v moves to L + // |----L--------U--v-| == v moves to U + if v < b.Lower { + v = b.Lower + } else if v > b.Upper { + v = b.Upper + } + // Afterwards we move L to 0, by calculating v = v - L + v = v - b.Lower + if b.SmallerIsBetter { + // If "SmallerIsBetter" is true then invert the value with the + // threshold. So, a 0 value becomes the threshold value and a + // value at the threshold becomes 0. + // TODO: consider how this affects the distribution + v = b.Threshold() - v + } + return v +} + +func (b Bounds) Threshold() float64 { + return b.Upper - b.Lower + +} + +type Input struct { + Bounds *Bounds + Weight float64 + Distribution *Distribution + Source Value + Tags []string +} + +func (i *Input) Value(fields map[string]float64) (float64, bool) { + v, ok := i.Source.Value(fields) + if !ok { + return 0, false + } + var den float64 = 1 + if i.Bounds != nil { + v = i.Bounds.Apply(v) + den = i.Distribution.Normalize(i.Bounds.Threshold()) + } + return i.Distribution.Normalize(v) / den, true +} diff --git a/cmd/scorer/algorithm/registry.go b/cmd/scorer/algorithm/registry.go new file mode 100644 index 00000000..eba0910b --- /dev/null +++ b/cmd/scorer/algorithm/registry.go @@ -0,0 +1,53 @@ +package algorithm + +import "fmt" + +// GlobalRegistry is the global, application wide, registry for all algorithms. +var GlobalRegistry = NewRegistry() + +// Registry is used to map a name to a Factory that creates Algorithm instances +// for the given name. +type Registry struct { + as map[string]Factory +} + +// NewRegistry returns a new Registry instance. +func NewRegistry() *Registry { + return &Registry{ + as: make(map[string]Factory), + } +} + +// Register adds the Factory for the corresponding Key to the registry. +// +// If another Factory has been registered with the same Key it will be +// replaced. +func (r *Registry) Register(name string, f Factory) { + r.as[name] = f +} + +// NewAlgorithm generates a new instance of Algorithm for the supplied name and +// fields. +// +// If the registry does not have a Factory for the supplied name an error will +// be returned. +// +// If the Algorithm fails to be created by the Factory, an error will also be +// returned and the Algorithm will be nil. +func (r *Registry) NewAlgorithm(name string, inputs []*Input) (Algorithm, error) { + f, ok := r.as[name] + if !ok { + return nil, fmt.Errorf("unknown algorithm %s", name) + } + return f(inputs) +} + +// Register calls Register on the GlobalRegistry. +func Register(name string, f Factory) { + GlobalRegistry.Register(name, f) +} + +// NewAlgorithm calls NewAlgorithm on the GlobalRegsitry. +func NewAlgorithm(name string, inputs []*Input) (Algorithm, error) { + return GlobalRegistry.NewAlgorithm(name, inputs) +} diff --git a/cmd/scorer/algorithm/value.go b/cmd/scorer/algorithm/value.go new file mode 100644 index 00000000..dfe4c2cc --- /dev/null +++ b/cmd/scorer/algorithm/value.go @@ -0,0 +1,61 @@ +package algorithm + +type Value interface { + // Value takes in a set of fields does some work and returns either the + // result and true to indicate success, or 0 and false to indicate + // the result could not be generated. + Value(fields map[string]float64) (float64, bool) +} + +// Field implements the Value interface, but simply returns the raw value of +// the named field. +type Field string + +func (f Field) String() string { + return string(f) +} + +// Value implements the Value interface. +func (f Field) Value(fields map[string]float64) (float64, bool) { + v, ok := fields[string(f)] + return v, ok +} + +type Condition func(fields map[string]float64) bool + +func NotCondition(c Condition) Condition { + return func(fields map[string]float64) bool { + return !c(fields) + } +} + +func ExistsCondition(f Field) Condition { + return func(fields map[string]float64) bool { + _, exists := fields[f.String()] + return exists + } +} + +// ConditionalValue wraps an Inner value that will only be returned if the +// Condition returns true. +type ConditionalValue struct { + Condition Condition + Inner Value +} + +// Value implements the Value interface. +func (cv *ConditionalValue) Value(fields map[string]float64) (float64, bool) { + v, ok := cv.Inner.Value(fields) + if !ok { + return 0, false + } + if cv.Condition(fields) { + return v, true + } else { + return 0, false + } +} + +// Condition struct { Eval(fields map[string]float64) bool } +// Not(Condition) Condition +// Exists(Field) Condition diff --git a/cmd/scorer/algorithm/wam/wam.go b/cmd/scorer/algorithm/wam/wam.go new file mode 100644 index 00000000..def88656 --- /dev/null +++ b/cmd/scorer/algorithm/wam/wam.go @@ -0,0 +1,38 @@ +// The package wam implements the Weighted Arithmetic Mean, which forms the +// basis of Rob Pike's criticality score algorithm as documented in +// Quantifying_criticality_algorithm.pdf. +package wam + +import ( + "github.com/ossf/criticality_score/cmd/scorer/algorithm" +) + +type WeighetedArithmeticMean struct { + inputs []*algorithm.Input +} + +// New returns a new instance of the Weighted Arithmetic Mean algorithm, which +// is used by the Pike algorithm. +func New(inputs []*algorithm.Input) (algorithm.Algorithm, error) { + return &WeighetedArithmeticMean{ + inputs: inputs, + }, nil +} + +func (p *WeighetedArithmeticMean) Score(record map[string]float64) float64 { + var totalWeight float64 + var s float64 + for _, i := range p.inputs { + v, ok := i.Value(record) + if !ok { + continue + } + totalWeight += i.Weight + s += i.Weight * v + } + return s / totalWeight +} + +func init() { + algorithm.Register("weighted_arithmetic_mean", New) +} diff --git a/cmd/scorer/config.go b/cmd/scorer/config.go new file mode 100644 index 00000000..cd509d00 --- /dev/null +++ b/cmd/scorer/config.go @@ -0,0 +1,127 @@ +package main + +import ( + "errors" + "fmt" + "io" + "io/ioutil" + + "github.com/ossf/criticality_score/cmd/scorer/algorithm" + "gopkg.in/yaml.v3" +) + +type Condition struct { + Not *Condition `yaml:"not"` + FieldExists string `yaml:"field_exists"` +} + +type Input struct { + Field string `yaml:"field"` + Weight float64 `yaml:"weight"` + Bounds *algorithm.Bounds `yaml:"bounds"` + Distribution string `yaml:"distribution"` + Condition *Condition `yaml:"condition"` + Tags []string `yaml:"tags"` +} + +// Implements yaml.Unmarshaler interface +func (i *Input) UnmarshalYAML(value *yaml.Node) error { + type RawInput Input + raw := &RawInput{ + Weight: 1, + Distribution: algorithm.DefaultDistributionName, + } + if err := value.Decode(raw); err != nil { + return err + } + if raw.Field == "" { + return errors.New("field must be set") + } + *i = Input(*raw) + return nil +} + +func buildCondition(c *Condition) (algorithm.Condition, error) { + if c.FieldExists != "" && c.Not != nil { + return nil, errors.New("only one field of condition must be set") + } + if c.FieldExists != "" { + return algorithm.ExistsCondition(algorithm.Field(c.FieldExists)), nil + } + if c.Not != nil { + innerC, err := buildCondition(c.Not) + if err != nil { + return nil, err + } + return algorithm.NotCondition(innerC), nil + } + return nil, errors.New("one condition field must be set") +} + +func (i *Input) ToAlgorithmInput() (*algorithm.Input, error) { + var v algorithm.Value + v = algorithm.Field(i.Field) + if i.Condition != nil { + c, err := buildCondition(i.Condition) + if err != nil { + return nil, err + } + v = &algorithm.ConditionalValue{ + Condition: c, + Inner: v, + } + } + d := algorithm.LookupDistribution(i.Distribution) + if d == nil { + return nil, fmt.Errorf("unknown distribution %s", i.Distribution) + } + return &algorithm.Input{ + Bounds: i.Bounds, + Weight: i.Weight, + Distribution: d, + Source: v, + Tags: i.Tags, + }, nil +} + +// Config is used to specify an algorithm and its given set of Fields and +// Options. +// +// This structure is used for parsing a YAML file and returning an instance of +// an Algorithm based on the configuration. +type Config struct { + Name string `yaml:"algorithm"` + Inputs []*Input `yaml:"inputs"` +} + +// LoadConfig will parse the YAML data from the reader and return a Config +// that can be used to obtain an Algorithm instance. +// +// If the data cannot be parsed an error will be returned. +func LoadConfig(r io.Reader) (*Config, error) { + c := &Config{} + data, err := ioutil.ReadAll(r) + if err != nil { + return nil, err + } + if err := yaml.Unmarshal(data, c); err != nil { + return nil, err + } + return c, nil +} + +// Algorithm returns an instance of Algorithm that is constructed from the +// Config. +// +// nil will be returned if the algorithm cannot be returned. +func (c *Config) Algorithm() (algorithm.Algorithm, error) { + var inputs []*algorithm.Input + for _, i := range c.Inputs { + input, err := i.ToAlgorithmInput() + if err != nil { + return nil, err + } + inputs = append(inputs, input) + } + return algorithm.NewAlgorithm(c.Name, inputs) +} diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go new file mode 100644 index 00000000..c4642670 --- /dev/null +++ b/cmd/scorer/main.go @@ -0,0 +1,231 @@ +// The scorer command is used for calculating the criticality score for signals +// generated by the collect_signals command. +// +// The scoring algorithm is defined by a YAML config file that defines the +// basic algorithm (e.g. "pike") and the fields to include in the score. Each +// field's upper and lower bounds, weight and distribution, and whether +// "smaller is better" can be set in the config. +// +// For example: +// +// algorithm: pike +// fields: +// legacy.created_since: +// weight: 1 +// upper: 120 +// distribution: zapfian +// +// The raw signals, along with the score, are returning in the output. +package main + +import ( + "encoding/csv" + "errors" + "flag" + "fmt" + "io" + "os" + "path" + "regexp" + "strconv" + "strings" + + _ "github.com/ossf/criticality_score/cmd/scorer/algorithm/wam" + "github.com/ossf/criticality_score/internal/logflag" + "github.com/ossf/criticality_score/internal/outfile" + log "github.com/sirupsen/logrus" +) + +const defaultLogLevel = log.InfoLevel + +var ( + configFlag = flag.String("config", "", "the filename of the config") + columnNameFlag = flag.String("column", "", "the name of the output column") + logFlag = logflag.Level(defaultLogLevel) +) + +func init() { + flag.Var(&logFlag, "log", "set the `level` of logging.") + outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") // TODO: add the ability to disable "append" + flag.Usage = func() { + cmdName := path.Base(os.Args[0]) + w := flag.CommandLine.Output() + fmt.Fprintf(w, "Usage:\n %s [FLAGS]... IN_CSV OUT_CSV\n\n", cmdName) + fmt.Fprintf(w, "Scores collected signal for record in the IN_CSV.\n") + fmt.Fprintf(w, "IN_CSV must be either a csv file or - to read from stdin.\n") + fmt.Fprintf(w, "OUT_CSV must be either be a csv file or - to write to stdout.\n") + fmt.Fprintf(w, "\nFlags:\n") + flag.PrintDefaults() + } +} + +func generateColumnName() string { + if *columnNameFlag != "" { + // If we have the column name, just use it as the name + return *columnNameFlag + } + // Get the name of the config file used, without the path + f := path.Base(*configFlag) + ext := path.Ext(f) + // Strip the extension and convert to lowercase + f = strings.ToLower(strings.TrimSuffix(f, ext)) + // Change any non-alphanumeric character into an underscore + f = regexp.MustCompile("[^a-z0-9_]").ReplaceAllString(f, "_") + // Append "_score" to the end + return f + "_score" +} + +func makeOutHeader(header []string, resultColumn string) ([]string, error) { + for _, h := range header { + if h == resultColumn { + return nil, fmt.Errorf("header already contains field %s", resultColumn) + } + } + return append(header, resultColumn), nil +} + +func makeRecord(header []string, row []string) map[string]float64 { + record := make(map[string]float64) + for i, k := range header { + raw := row[i] + v, err := strconv.ParseFloat(raw, 64) + if err != nil { + // Failed to parse raw into a float, ignore the field + continue + } + record[k] = v + } + return record +} + +func main() { + flag.Parse() + + logger := log.New() + logger.SetLevel(logFlag.Level()) + + if flag.NArg() != 2 { + logger.Error("Must have an input file and an output file specified") + os.Exit(2) + } + inFilename := flag.Args()[0] + outFilename := flag.Args()[1] + + // Open the in-file for reading + var r *csv.Reader + if inFilename == "-" { + logger.Info("Reading from stdin") + r = csv.NewReader(os.Stdin) + } else { + logger.WithFields(log.Fields{ + "filename": inFilename, + }).Debug("Reading from file") + f, err := os.Open(inFilename) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "filename": inFilename, + }).Error("Failed to open input file") + os.Exit(2) + } + defer f.Close() + r = csv.NewReader(f) + } + + // Open the out-file for writing + f, err := outfile.Open(outFilename) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "filename": outFilename, + }).Error("Failed to open file for output") + os.Exit(2) + } + defer f.Close() + w := csv.NewWriter(f) + defer w.Flush() + + // Prepare the algorithm from the config file + if *configFlag == "" { + logger.Error("Must have a config file set") + os.Exit(2) + } + + f, err = os.Open(*configFlag) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "filename": configFlag, + }).Error("Failed to open config file") + os.Exit(2) + } + c, err := LoadConfig(f) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "filename": configFlag, + }).Error("Failed to parse config file") + os.Exit(2) + } + a, err := c.Algorithm() + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + "algorithm": c.Name, + }).Error("Failed to get the algorithm") + os.Exit(2) + } + + inHeader, err := r.Read() + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to read CSV header row") + os.Exit(2) + } + + // Generate and output the CSV header row + outHeader, err := makeOutHeader(inHeader, generateColumnName()) + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to generate output header row") + os.Exit(2) + } + if err := w.Write(outHeader); err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to write CSV header row") + os.Exit(2) + } + + var pq PriorityQueue + for { + row, err := r.Read() + if errors.Is(err, io.EOF) { + break + } + if err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to read CSV row") + os.Exit(2) + } + record := makeRecord(inHeader, row) + score := a.Score(record) + row = append(row, fmt.Sprintf("%.5f", score)) + pq.PushRow(row, score) + } + + // Iterate over the pq and send the results to the output csv. + t := pq.Len() + for i := 0; i < t; i++ { + if err := w.Write(pq.PopRow()); err != nil { + logger.WithFields(log.Fields{ + "error": err, + }).Error("Failed to write CSV header row") + os.Exit(2) + } + } + // -allow-score-override -- if the output field exists overwrite the existing data +} diff --git a/cmd/scorer/pq.go b/cmd/scorer/pq.go new file mode 100644 index 00000000..2ee54786 --- /dev/null +++ b/cmd/scorer/pq.go @@ -0,0 +1,66 @@ +package main + +import "container/heap" + +// A RowItem is something to manage in a priority queue. +type RowItem struct { + row []string + score float64 + // The index is needed by update and is maintained by the heap.Interface methods. + index int // The index of the item in the heap. +} + +// A PriorityQueue implements heap.Interface and holds RowItems. +// +// The implementation of PriorityQueue is largely copied from the +// "container/heap" documentation. +type PriorityQueue []*RowItem + +// Len implements the heap.Interface interface +func (pq PriorityQueue) Len() int { return len(pq) } + +// Less implements the heap.Interface interface +func (pq PriorityQueue) Less(i, j int) bool { + // We want Pop to give us the highest, not lowest, priority so we use greater than here. + return pq[i].score > pq[j].score +} + +// Swap implements the heap.Interface interface +func (pq PriorityQueue) Swap(i, j int) { + pq[i], pq[j] = pq[j], pq[i] + pq[i].index = i + pq[j].index = j +} + +// Push implements the heap.Interface interface +func (pq *PriorityQueue) Push(x any) { + n := len(*pq) + item := x.(*RowItem) + item.index = n + *pq = append(*pq, item) +} + +// Pop implements the heap.Interface interface +func (pq *PriorityQueue) Pop() any { + old := *pq + n := len(old) + item := old[n-1] + old[n-1] = nil // avoid memory leak + item.index = -1 // for safety + *pq = old[0 : n-1] + return item +} + +// PushRow will add the given row into the priority queue with the score as the +// priority. +func (pq *PriorityQueue) PushRow(row []string, score float64) { + heap.Push(pq, &RowItem{ + row: row, + score: score, + }) +} + +// PopRow returns the row with the highest score. +func (pq *PriorityQueue) PopRow() []string { + return heap.Pop(pq).(*RowItem).row +} diff --git a/config/scorer/original_pike.yml b/config/scorer/original_pike.yml new file mode 100644 index 00000000..a080cdb0 --- /dev/null +++ b/config/scorer/original_pike.yml @@ -0,0 +1,65 @@ +# The original set of weights defined for the criticality score project using +# Rob Pike's algorithm as implemented in the original Python project. +algorithm: weighted_arithmetic_mean + +inputs: + - field: legacy.created_since + weight: 1 + bounds: + upper: 120 + distribution: zapfian + + - field: legacy.updated_since + weight: 1 + bounds: + upper: 120 + smaller_is_better: yes + distribution: zapfian + + - field: legacy.contributor_count + weight: 2 + bounds: + upper: 5000 + distribution: zapfian + + - field: legacy.org_count + weight: 1 + bounds: + upper: 10 + distribution: zapfian + + - field: legacy.commit_frequency + weight: 1 + bounds: + upper: 1000 + distribution: zapfian + + - field: legacy.recent_release_count + weight: 0.5 + bounds: + upper: 26 + distribution: zapfian + + - field: legacy.updated_issues_count + weight: 0.5 + bounds: + upper: 5000 + distribution: zapfian + + - field: legacy.closed_issues_count + weight: 0.5 + bounds: + upper: 5000 + distribution: zapfian + + - field: legacy.issue_comment_frequency + weight: 1 + bounds: + upper: 15 + distribution: zapfian + + - field: legacy.github_mention_count + weight: 2 + bounds: + upper: 500000 + distribution: zapfian diff --git a/config/scorer/pike_depsdev.yml b/config/scorer/pike_depsdev.yml new file mode 100644 index 00000000..d7b7933a --- /dev/null +++ b/config/scorer/pike_depsdev.yml @@ -0,0 +1,84 @@ +algorithm: weighted_arithmetic_mean + +inputs: + - field: legacy.created_since + weight: 1 + bounds: + upper: 120 + distribution: zapfian + + - field: legacy.updated_since + weight: 1 + bounds: + upper: 120 + smaller_is_better: yes + distribution: zapfian + + - field: legacy.contributor_count + weight: 2 + bounds: + upper: 5000 + distribution: zapfian + + - field: legacy.org_count + weight: 1 + bounds: + upper: 10 + distribution: zapfian + + - field: legacy.commit_frequency + weight: 1 + bounds: + upper: 1000 + distribution: zapfian + + - field: legacy.recent_release_count + weight: 0.5 + bounds: + upper: 26 + distribution: zapfian + + - field: legacy.updated_issues_count + weight: 0.5 + bounds: + upper: 5000 + distribution: zapfian + + - field: legacy.closed_issues_count + weight: 0.5 + bounds: + upper: 5000 + distribution: zapfian + + - field: legacy.issue_comment_frequency + weight: 1 + bounds: + upper: 15 + distribution: zapfian + + # If deps.dev dependenct count doesn't exist we use this configuration + # for the GitHub search mention count. + - field: legacy.github_mention_count + weight: 2 + bounds: + upper: 500000 + condition: + not: + field_exists: "depsdev.dependent_count" + distribution: zapfian + + # If deps.dev dependent count *does* exist we lower the importance of + # the GitHub search mention count. + - field: legacy.github_mention_count + weight: 1 + bounds: + upper: 500000 + condition: + field_exists: "depsdev.dependent_count" + distribution: zapfian + + - field: depsdev.dependent_count + weight: 4 + bounds: + upper: 200000 + distribution: zapfian From 282b7d066ecda387d896f00715aada328e5f0fb2 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 17 Jun 2022 15:04:49 +1000 Subject: [PATCH 069/172] Fix a bug where the params where set in the query. (#134) --- cmd/collect_signals/depsdev/bq.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/cmd/collect_signals/depsdev/bq.go b/cmd/collect_signals/depsdev/bq.go index 2c15dcab..dad8fad8 100644 --- a/cmd/collect_signals/depsdev/bq.go +++ b/cmd/collect_signals/depsdev/bq.go @@ -39,6 +39,9 @@ func (b *bq) Project() string { func (b *bq) OneResultQuery(ctx context.Context, query string, params map[string]any, result any) error { q := b.client.Query(query) + for k, v := range params { + q.Parameters = append(q.Parameters, bigquery.QueryParameter{Name: k, Value: v}) + } it, err := q.Read(ctx) if err != nil { return err From b1019338a85cb9cd06e425ccf30d9a05a86b1d22 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 17 Jun 2022 15:22:38 +1000 Subject: [PATCH 070/172] Handle the case where GitHub returns 5xx when there are lots of issues (#135) --- cmd/collect_signals/github/collector.go | 45 ++++++++++--------- .../github/legacy/constants.go | 10 +++-- cmd/collect_signals/github/legacy/issues.go | 4 ++ internal/githubapi/roundtripper.go | 10 ++++- 4 files changed, 42 insertions(+), 27 deletions(-) diff --git a/cmd/collect_signals/github/collector.go b/cmd/collect_signals/github/collector.go index 07891300..0de22f21 100644 --- a/cmd/collect_signals/github/collector.go +++ b/cmd/collect_signals/github/collector.go @@ -86,38 +86,39 @@ func (ic *IssuesCollector) Collect(ctx context.Context, r projectrepo.Repo) (sig } s := &signal.IssuesSet{} + ghr.logger.Debug("Fetching closed issues") + closed, err := legacy.FetchIssueCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueStateClosed, legacy.IssueLookback) + if err != nil { + return nil, err + } + s.ClosedCount.Set(closed) + // TODO: the calculation of the frequency should be moved into the legacy // package. Ideally this would be behind an struct/interface that allows // caching and also removes the need to pass client, owner and name to each // function call. ghr.logger.Debug("Fetching updated issues") - if up, err := legacy.FetchIssueCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueStateAll, legacy.IssueLookback); err != nil { + up, err := legacy.FetchIssueCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueStateAll, legacy.IssueLookback) + if err != nil { return nil, err - } else { - s.UpdatedCount.Set(up) - if up != 0 { - ghr.logger.Debug("Fetching comment frequency") - if comments, err := legacy.FetchIssueCommentCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueLookback); err != nil { - if errors.Is(err, legacy.TooManyResultsError) { - ghr.logger.Debug("Comment count failed with too many result") - s.CommentFrequency.Set(legacy.TooManyCommentsFrequency) - } else { - return nil, err - } - } else { - s.CommentFrequency.Set(legacy.Round(float64(comments)/float64(up), 2)) - } - } else { - s.CommentFrequency.Set(0) - } } - ghr.logger.Debug("Fetching closed issues") - if closed, err := legacy.FetchIssueCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueStateClosed, legacy.IssueLookback); err != nil { + s.UpdatedCount.Set(up) + + if up == 0 { + s.CommentFrequency.Set(0) + return s, nil + } + + ghr.logger.Debug("Fetching comment frequency") + comments, err := legacy.FetchIssueCommentCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueLookback) + if errors.Is(err, legacy.TooManyResultsError) { + ghr.logger.Debug("Comment count failed with too many result") + s.CommentFrequency.Set(legacy.TooManyCommentsFrequency) + } else if err != nil { return nil, err } else { - s.ClosedCount.Set(closed) + s.CommentFrequency.Set(legacy.Round(float64(comments)/float64(up), 2)) } - return s, nil } diff --git a/cmd/collect_signals/github/legacy/constants.go b/cmd/collect_signals/github/legacy/constants.go index a008bead..1d1c587c 100644 --- a/cmd/collect_signals/github/legacy/constants.go +++ b/cmd/collect_signals/github/legacy/constants.go @@ -9,11 +9,13 @@ const ( SinceDuration time.Duration = time.Hour * 24 * 30 IssueLookback time.Duration = time.Hour * 24 * 90 * 24 - MaxContributorLimit = 5000 - MaxTopContributors = 15 - TooManyContributorsOrgCount = 10 + // TODO: these limits should ultimately be imposed by the score generation, not here. + MaxContributorLimit = 5000 + MaxIssuesLimit = 5000 + MaxTopContributors = 15 - TooManyCommentsFrequency = 2.0 + TooManyContributorsOrgCount = 10 + TooManyCommentsFrequency = 2.0 releasesPerPage = 100 ) diff --git a/cmd/collect_signals/github/legacy/issues.go b/cmd/collect_signals/github/legacy/issues.go index 4bf67ad7..f38b0d80 100644 --- a/cmd/collect_signals/github/legacy/issues.go +++ b/cmd/collect_signals/github/legacy/issues.go @@ -27,6 +27,10 @@ func FetchIssueCount(ctx context.Context, c *githubapi.Client, owner, name strin ListOptions: github.ListOptions{PerPage: 1}, // 1 result per page means LastPage is total number of records. } is, resp, err := c.Rest().Issues.ListByRepo(ctx, owner, name, opts) + // The API returns 5xx responses if there are too many issues. + if c := githubapi.ErrorResponseStatusCode(err); 500 <= c && c < 600 { + return MaxIssuesLimit, nil + } if err != nil { return 0, err } diff --git a/internal/githubapi/roundtripper.go b/internal/githubapi/roundtripper.go index f1b1972c..43eb0675 100644 --- a/internal/githubapi/roundtripper.go +++ b/internal/githubapi/roundtripper.go @@ -20,6 +20,7 @@ const ( ) var ( + issuesRe = regexp.MustCompile("^repos/[^/]+/[^/]+/issues$") issueCommentsRe = regexp.MustCompile("^repos/[^/]+/[^/]+/issues/comments$") ) @@ -54,7 +55,14 @@ func (s *strategies) ServerError(r *http.Response) (retry.RetryStrategy, error) return retry.NoRetry, nil } s.logger.WithField("status", r.Status).Warn("5xx: detected") - if issueCommentsRe.MatchString(strings.Trim(r.Request.URL.Path, "/")) { + path := strings.Trim(r.Request.URL.Path, "/") + if issuesRe.MatchString(path) { + s.logger.Warn("Ignoring /repos/X/Y/issues url.") + // If the req url was /repos/[owner]/[name]/issues pass the + // error through as it is likely a GitHub bug. + return retry.NoRetry, nil + } + if issueCommentsRe.MatchString(path) { s.logger.Warn("Ignoring /repos/X/Y/issues/comments url.") // If the req url was /repos/[owner]/[name]/issues/comments pass the // error through as it is likely a GitHub bug. From 69312d19449429a28347e997bdb1775bb994380c Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 7 Jul 2022 13:51:56 +1000 Subject: [PATCH 071/172] Add a README for the enumerate_github command. (#141) * Add a README for the enumerate_github command. --- cmd/enumerate_github/README.md | 133 +++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 cmd/enumerate_github/README.md diff --git a/cmd/enumerate_github/README.md b/cmd/enumerate_github/README.md new file mode 100644 index 00000000..f61869da --- /dev/null +++ b/cmd/enumerate_github/README.md @@ -0,0 +1,133 @@ +# GitHub Enumeration Tool + +This tool is used to reliably enumerate projects on GitHub. + +The output of this tool is used as an input for the `collect_signals` tool. + +## Example + +```shell +$ export GITHUB_TOKEN=ghp_x # Personal Access Token Goes Here +$ enumerate_github \ + -start 2008-01-01 \ + -min-stars=10 \ + -workers=1 \ + github_projects.txt +``` + +## Install + +```shell +$ go install github.com/ossf/criticality_score/cmd/enumerate_github +``` + +## Usage + +```shell +$ enumerate_github [FLAGS]... FILE +``` + +The URL for each repository is written to `FILE`. If `FILE` is `-` the results will be written to STDOUT. + +`FLAGS` are optional. See below for documentation. + +### Authentication + +A comma delimited environment variable with one or more GitHub Personal Access +Tokens must be set + +Supported environment variables are `GITHUB_AUTH_TOKEN`, `GITHUB_TOKEN`, +`GH_TOKEN`, or `GH_AUTH_TOKEN`. + +Example: + +```shell +$ export GITHUB_TOKEN=ghp_abc,ghp_123 +``` + +### Flags + +#### Output flags + +- `-append` appends output to `FILE` if it already exists. +- `-force` overwrites `FILE` if it already exists and `-append` is not set. + +If `FILE` exists and neither `-append` nor `-force` is set the command will fail. + +#### Date flags + +- `-start date` + the start date to enumerate back to. Must be at or after `2008-01-01`. Defaults to `2008-01-01`. +- `-end date` + the end date to enumerate from. Defaults to today's date. + +#### Query/Star flags + +- `-min-stars int` only enumerates repositories with this or more of stars + Defaults to `10`. +- `-query string` sets the base query to use for enumeration. Defaults to + `is:public`. See GitHub's [search help](https://docs.github.com/en/search-github/searching-on-github/searching-for-repositories) + for more detail. +- `-require-min-stars` abort execution if `-min-stars` can't be reached during + enumeration. If not set some repositories created on a certain date may not + be included. +- `-star-overlap int` the number of stars to overlap between queries. Defaults + to `5`. A an overlap is used to avoid missing repositories whose star count + changes during enumeration. + +#### Misc Flags + +- `-log level` set the level of logging. Can be `debug`, `info` (default), `warn` or `error`. +- `-workers int` the total number of concurrent workers to use. Default is `1`. +- `-help` displays help text. + +## How It Works + +Refer to [Milestone 1](../../docs/design/milestone_1.md) for details on the +algorithm. + +## Q&A + +### Q: What is the lowest practical setting for `-min-stars` + +10 has been successfully tested, although lower may be possible. + +*TODO* -- more detail + +### Q: How long does it take? + +A single GitHub Personal Access Token took about 4 hours to return all +projects with >= 20 stars. + +Faster performance can be achieved with more Personal Access Tokens and +additional workers. + +### Q: How many workers should I use? + +Generally, use 1 worker for each Personal Access Token. + +More workers than tokens may result in secondary rate limits. + +It is possible that more restricted searches will succeed with more workers per +token. + +## Development + +Rather than installing the binary, use `go run` to run the command. + +For example: + +```shell +$ go run ./cmd/enumerate_github [FLAGS]... FILE +``` + +Limiting the data allows for runs to be completed quickly. For example: + +```shell +$ go run ./cmd/enumerate_github \ + -log=debug \ + -start=2022-06-14 \ + -end=2022-06-21 \ + -min-stars=20 \ + - +``` \ No newline at end of file From 16e366574bc5cc9ff011c270ac1114476889853f Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 12 Jul 2022 12:15:49 +1000 Subject: [PATCH 072/172] Backport flag.TextVar from Go 1.19 to replace logflag. (#144) * Add a backport of Go 1.19's flag.TextVar function to replace logflag. * Switch from logflag to textvarflag. * Remove logflag now that it is unused. * Add license and attribution to textvarflag --- cmd/collect_signals/main.go | 8 +-- cmd/enumerate_github/main.go | 29 ++-------- cmd/scorer/main.go | 20 +++---- internal/logflag/level.go | 32 ----------- internal/logflag/level_test.go | 78 -------------------------- internal/textvarflag/flag.go | 92 +++++++++++++++++++++++++++++++ internal/textvarflag/flag_test.go | 48 ++++++++++++++++ 7 files changed, 158 insertions(+), 149 deletions(-) delete mode 100644 internal/logflag/level.go delete mode 100644 internal/logflag/level_test.go create mode 100644 internal/textvarflag/flag.go create mode 100644 internal/textvarflag/flag_test.go diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 66da6978..b56c30cd 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -19,8 +19,8 @@ import ( "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/cmd/collect_signals/result" "github.com/ossf/criticality_score/internal/githubapi" - "github.com/ossf/criticality_score/internal/logflag" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" sclog "github.com/ossf/scorecard/v4/log" @@ -32,11 +32,11 @@ const defaultLogLevel = log.InfoLevel var ( gcpProjectFlag = flag.String("gcp-project", "", "the Google Cloud Project to use. Required for deps.dev data collection.") workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") - logFlag = logflag.Level(defaultLogLevel) + logLevel log.Level ) func init() { - flag.Var(&logFlag, "log", "set the `level` of logging.") + textvarflag.TextVar(flag.CommandLine, &logLevel, "log", defaultLogLevel, "set the `level` of logging.") outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -95,7 +95,7 @@ func main() { flag.Parse() logger := log.New() - logger.SetLevel(logFlag.Level()) + logger.SetLevel(logLevel) // roundtripper requires us to use the scorecard logger. scLogger := sclog.NewLogrusLogger(logger) diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 664de405..ba3e36c8 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -11,8 +11,8 @@ import ( "time" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" - "github.com/ossf/criticality_score/internal/logflag" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" sclog "github.com/ossf/scorecard/v4/log" @@ -38,7 +38,7 @@ var ( workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") startDateFlag = dateFlag(epochDate) endDateFlag = dateFlag(time.Now().UTC().Truncate(oneDay)) - logFlag = logflag.Level(defaultLogLevel) + logLevel log.Level ) // dateFlag implements the flag.Value interface to simplify the input and validation of @@ -62,31 +62,10 @@ func (d *dateFlag) Time() time.Time { return (time.Time)(*d) } -// logLevelFlag implements the flag.Value interface to simplify the input and validation -// of the current log level. -type logLevelFlag log.Level - -func (l *logLevelFlag) Set(value string) error { - level, err := log.ParseLevel(string(value)) - if err != nil { - return err - } - *l = logLevelFlag(level) - return nil -} - -func (l logLevelFlag) String() string { - return log.Level(l).String() -} - -func (l logLevelFlag) Level() log.Level { - return log.Level(l) -} - func init() { flag.Var(&startDateFlag, "start", "the start `date` to enumerate back to. Must be at or after 2008-01-01.") flag.Var(&endDateFlag, "end", "the end `date` to enumerate from.") - flag.Var(&logFlag, "log", "set the `level` of logging.") + textvarflag.TextVar(flag.CommandLine, &logLevel, "log", defaultLogLevel, "set the `level` of logging.") outfile.DefineFlags(flag.CommandLine, "force", "append", "FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -133,7 +112,7 @@ func main() { flag.Parse() logger := log.New() - logger.SetLevel(logFlag.Level()) + logger.SetLevel(logLevel) // roundtripper requires us to use the scorecard logger. scLogger := sclog.NewLogrusLogger(logger) diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index c4642670..05c00b0c 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -8,12 +8,12 @@ // // For example: // -// algorithm: pike -// fields: -// legacy.created_since: -// weight: 1 -// upper: 120 -// distribution: zapfian +// algorithm: pike +// fields: +// legacy.created_since: +// weight: 1 +// upper: 120 +// distribution: zapfian // // The raw signals, along with the score, are returning in the output. package main @@ -31,8 +31,8 @@ import ( "strings" _ "github.com/ossf/criticality_score/cmd/scorer/algorithm/wam" - "github.com/ossf/criticality_score/internal/logflag" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/textvarflag" log "github.com/sirupsen/logrus" ) @@ -41,11 +41,11 @@ const defaultLogLevel = log.InfoLevel var ( configFlag = flag.String("config", "", "the filename of the config") columnNameFlag = flag.String("column", "", "the name of the output column") - logFlag = logflag.Level(defaultLogLevel) + logLevel log.Level ) func init() { - flag.Var(&logFlag, "log", "set the `level` of logging.") + textvarflag.TextVar(flag.CommandLine, &logLevel, "log", defaultLogLevel, "set the `level` of logging.") outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") // TODO: add the ability to disable "append" flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -102,7 +102,7 @@ func main() { flag.Parse() logger := log.New() - logger.SetLevel(logFlag.Level()) + logger.SetLevel(logLevel) if flag.NArg() != 2 { logger.Error("Must have an input file and an output file specified") diff --git a/internal/logflag/level.go b/internal/logflag/level.go deleted file mode 100644 index 7014e69e..00000000 --- a/internal/logflag/level.go +++ /dev/null @@ -1,32 +0,0 @@ -// Package logflag is a simple helper library that generalizes the logic for -// parsing command line flags for configuring the logging behavior. -package logflag - -import log "github.com/sirupsen/logrus" - -// Level implements the flag.Value interface to simplify the input and validation -// of the current logrus log level. -// -// var logLevel = logflag.Level(logrus.InfoLevel) -// flag.Var(&logLevel, "log", "set the `level` of logging.") -type Level log.Level - -// Set implements the flag.Value interface. -func (l *Level) Set(value string) error { - level, err := log.ParseLevel(string(value)) - if err != nil { - return err - } - *l = Level(level) - return nil -} - -// String implements the flag.Value interface. -func (l Level) String() string { - return log.Level(l).String() -} - -// Level returns either the default log level, or the value set on the command line. -func (l Level) Level() log.Level { - return log.Level(l) -} diff --git a/internal/logflag/level_test.go b/internal/logflag/level_test.go deleted file mode 100644 index 73f2605b..00000000 --- a/internal/logflag/level_test.go +++ /dev/null @@ -1,78 +0,0 @@ -package logflag_test - -import ( - "flag" - "testing" - - "github.com/ossf/criticality_score/internal/logflag" - "github.com/sirupsen/logrus" -) - -func TestDefault(t *testing.T) { - level := logflag.Level(logrus.ErrorLevel) - if l := level.Level(); l != logrus.ErrorLevel { - t.Fatalf("Level() == %v, want %v", l, logrus.ErrorLevel) - } -} - -func TestSet(t *testing.T) { - level := logflag.Level(logrus.InfoLevel) - err := level.Set("error") - if err != nil { - t.Fatalf("Set() == %v, want nil", err) - } - if l := level.Level(); l != logrus.ErrorLevel { - t.Fatalf("Level() == %v, want %v", l, logrus.ErrorLevel) - } -} - -func TestSetError(t *testing.T) { - level := logflag.Level(logrus.InfoLevel) - err := level.Set("hello,world") - if err == nil { - t.Fatalf("Set() == nil, want an error") - } -} - -func TestString(t *testing.T) { - level := logflag.Level(logrus.DebugLevel) - if s := level.String(); s != logrus.DebugLevel.String() { - t.Fatalf("String() == %v, want %v", s, logrus.DebugLevel.String()) - } -} - -func TestFlagUnset(t *testing.T) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - level := logflag.Level(logrus.InfoLevel) - fs.Var(&level, "level", "usage") - err := fs.Parse([]string{"arg"}) - if err != nil { - t.Fatalf("Parse() == %v, want nil", err) - } - if l := level.Level(); l != logrus.InfoLevel { - t.Fatalf("Level() == %v, want %v", l, logrus.InfoLevel) - } -} - -func TestFlagSet(t *testing.T) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - level := logflag.Level(logrus.InfoLevel) - fs.Var(&level, "level", "usage") - err := fs.Parse([]string{"-level=fatal", "arg"}) - if err != nil { - t.Fatalf("Parse() == %v, want nil", err) - } - if l := level.Level(); l != logrus.FatalLevel { - t.Fatalf("Level() == %v, want %v", l, logrus.FatalLevel) - } -} - -func TestFlagSetError(t *testing.T) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - level := logflag.Level(logrus.InfoLevel) - fs.Var(&level, "level", "usage") - err := fs.Parse([]string{"-level=foobar", "arg"}) - if err == nil { - t.Fatalf("Parse() == nil, want an error") - } -} diff --git a/internal/textvarflag/flag.go b/internal/textvarflag/flag.go new file mode 100644 index 00000000..a9f77e11 --- /dev/null +++ b/internal/textvarflag/flag.go @@ -0,0 +1,92 @@ +/* +Copyright (c) 2009 The Go Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above +copyright notice, this list of conditions and the following disclaimer +in the documentation and/or other materials provided with the +distribution. + * Neither the name of Google Inc. nor the names of its +contributors may be used to endorse or promote products derived from +this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +/* +Package textvarflag is a backport of flag.TextVar from Go 1.19. + +Source: https://cs.opensource.google/go/go/+/master:src/flag/flag.go. + +Once Go 1.19 has been released this package can be removed. +*/ +package textvarflag + +import ( + "encoding" + "flag" + "fmt" + "reflect" +) + +// -- encoding.TextUnmarshaler Value +type textValue struct{ p encoding.TextUnmarshaler } + +func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue { + ptrVal := reflect.ValueOf(p) + if ptrVal.Kind() != reflect.Ptr { + panic("variable value type must be a pointer") + } + defVal := reflect.ValueOf(val) + if defVal.Kind() == reflect.Ptr { + defVal = defVal.Elem() + } + if defVal.Type() != ptrVal.Type().Elem() { + panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem())) + } + ptrVal.Elem().Set(defVal) + return textValue{p} +} + +func (v textValue) Set(s string) error { + return v.p.UnmarshalText([]byte(s)) +} + +func (v textValue) Get() interface{} { + return v.p +} + +func (v textValue) String() string { + if m, ok := v.p.(encoding.TextMarshaler); ok { + if b, err := m.MarshalText(); err == nil { + return string(b) + } + } + return "" +} + +// TextVar defines a flag with a specified name, default value, and usage string. +// The argument p must be a pointer to a variable that will hold the value +// of the flag, and p must implement encoding.TextUnmarshaler. +// If the flag is used, the flag value will be passed to p's UnmarshalText method. +// The type of the default value must be the same as the type of p. +// +// TextVar is a backport of the 1.19 implementation of flag.TextVar. +func TextVar(fs *flag.FlagSet, p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) { + fs.Var(newTextValue(value, p), name, usage) +} diff --git a/internal/textvarflag/flag_test.go b/internal/textvarflag/flag_test.go new file mode 100644 index 00000000..fd4f7997 --- /dev/null +++ b/internal/textvarflag/flag_test.go @@ -0,0 +1,48 @@ +package textvarflag_test + +import ( + "flag" + "net" + "testing" + + "github.com/ossf/criticality_score/internal/textvarflag" + "github.com/sirupsen/logrus" +) + +var defaultIP = net.IPv4(192, 168, 0, 100) + +func TestFlagUnset(t *testing.T) { + fs := flag.NewFlagSet("", flag.ContinueOnError) + var ip net.IP + textvarflag.TextVar(fs, &ip, "ip", defaultIP, "usage") + err := fs.Parse([]string{"arg"}) + if err != nil { + t.Fatalf("Parse() == %v, want nil", err) + } + if !defaultIP.Equal(ip) { + t.Fatalf("ip == %v, want %v", ip, defaultIP) + } +} + +func TestFlagSet(t *testing.T) { + fs := flag.NewFlagSet("", flag.ContinueOnError) + var ip net.IP + textvarflag.TextVar(fs, &ip, "ip", defaultIP, "usage") + err := fs.Parse([]string{"-ip=127.0.0.1", "arg"}) + if err != nil { + t.Fatalf("Parse() == %v, want nil", err) + } + if expect := net.IPv4(127, 0, 0, 1); !expect.Equal(ip) { + t.Fatalf("ip == %v, want %v", ip, logrus.FatalLevel) + } +} + +func TestFlagSetError(t *testing.T) { + fs := flag.NewFlagSet("", flag.ContinueOnError) + var ip net.IP + textvarflag.TextVar(fs, &ip, "ip", defaultIP, "usage") + err := fs.Parse([]string{"-ip=256.0.0.1", "arg"}) + if err == nil { + t.Fatalf("Parse() == nil, want an error") + } +} From 5e8a4b01fd5a1d440ff47a501011f7bf87d804f3 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 12 Jul 2022 15:42:41 +1000 Subject: [PATCH 073/172] Woops. != 404 should be == 404 (#145) --- cmd/collect_signals/depsdev/bq.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmd/collect_signals/depsdev/bq.go b/cmd/collect_signals/depsdev/bq.go index dad8fad8..56f73eb4 100644 --- a/cmd/collect_signals/depsdev/bq.go +++ b/cmd/collect_signals/depsdev/bq.go @@ -116,5 +116,5 @@ func isNotFound(err error) bool { return false } apiErr, ok := err.(*googleapi.Error) - return ok && apiErr.Code != 404 + return ok && apiErr.Code == 404 } From d3c3aab4f0f94666826baccb327b58fc7e23a843 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 12 Jul 2022 16:15:13 +1000 Subject: [PATCH 074/172] Improve deps.dev support with new flags and GCP project autodetect (#146) - gcp project id is autodetected now. - deps.dev requires explicit disabling to improve usability. - deps.dev dataset name can be set from the command line. --- cmd/collect_signals/depsdev/collector.go | 15 ++++++++------- cmd/collect_signals/depsdev/dependents.go | 21 +++++++++++++-------- cmd/collect_signals/main.go | 23 +++++++++++------------ 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/cmd/collect_signals/depsdev/collector.go b/cmd/collect_signals/depsdev/collector.go index f2bfa88e..f7b49391 100644 --- a/cmd/collect_signals/depsdev/collector.go +++ b/cmd/collect_signals/depsdev/collector.go @@ -13,6 +13,7 @@ import ( ) const defaultLocation = "US" +const DefaultDatasetName = "depsdev_analysis" type depsDevSet struct { DependentCount signal.Field[int] `signal:"dependent_count"` @@ -56,12 +57,12 @@ func (c *depsDevCollector) Collect(ctx context.Context, r projectrepo.Repo) (sig // NewCollector creates a new Collector for gathering data from deps.dev. // // TODO add options to configure the dataset: -// - an optional projectID -// - datasetname -// - when to expire the dataset (maybe?) -// - force dataset re-creation (-update-strategy = always,stale,weekly,monthly,never) -// - force dataset destruction (-depsdev-destroy-data) -func NewCollector(ctx context.Context, logger *log.Logger, projectID string) (collector.Collector, error) { +// - force dataset re-creation (-update-strategy = always,stale,weekly,monthly,never) +// - force dataset destruction (-depsdev-destroy-data) +func NewCollector(ctx context.Context, logger *log.Logger, projectID, datasetName string) (collector.Collector, error) { + if projectID == "" { + projectID = bigquery.DetectProjectID + } gcpClient, err := bigquery.NewClient(ctx, projectID) if err != nil { return nil, err @@ -69,7 +70,7 @@ func NewCollector(ctx context.Context, logger *log.Logger, projectID string) (co // Set the location gcpClient.Location = defaultLocation - dependents, err := NewDependents(ctx, gcpClient, logger) + dependents, err := NewDependents(ctx, gcpClient, logger, datasetName) if err != nil { return nil, err } diff --git a/cmd/collect_signals/depsdev/dependents.go b/cmd/collect_signals/depsdev/dependents.go index 1ff81972..d296cd8d 100644 --- a/cmd/collect_signals/depsdev/dependents.go +++ b/cmd/collect_signals/depsdev/dependents.go @@ -13,7 +13,6 @@ import ( ) const ( - datasetName = "depsdev_analysis" dependentCountsTableName = "dependent_counts" packageVersionToProjectTableName = "package_version_to_project" @@ -54,10 +53,15 @@ FROM ` + "`{{.ProjectID}}.{{.DatasetName}}.{{.TableName}}`" + ` WHERE ProjectName = @projectname AND ProjectType = @projecttype; ` -func NewDependents(ctx context.Context, client *bigquery.Client, logger *log.Logger) (*dependents, error) { +func NewDependents(ctx context.Context, client *bigquery.Client, logger *log.Logger, datasetName string) (*dependents, error) { + b := &bq{client: client} c := &dependents{ - b: &bq{client: client}, - logger: logger, + b: b, + logger: logger.WithFields(log.Fields{ + "project_id": b.Project(), + "dataset": datasetName, + }), + datasetName: datasetName, } var err error @@ -96,9 +100,10 @@ func NewDependents(ctx context.Context, client *bigquery.Client, logger *log.Log type dependents struct { b bqAPI - logger *log.Logger + logger *log.Entry snapshotTime time.Time countQuery string + datasetName string } func (c *dependents) generateQuery(temp string) string { @@ -108,7 +113,7 @@ func (c *dependents) generateQuery(temp string) string { ProjectID string DatasetName string TableName string - }{c.b.Project(), datasetName, dependentCountsTableName}) + }{c.b.Project(), c.datasetName, dependentCountsTableName}) return b.String() } @@ -146,14 +151,14 @@ func (c *dependents) getLatestSnapshotTime(ctx context.Context) (time.Time, erro func (c *dependents) getOrCreateDataset(ctx context.Context) (*Dataset, error) { // Attempt to get the current dataset - ds, err := c.b.GetDataset(ctx, datasetName) + ds, err := c.b.GetDataset(ctx, c.datasetName) if err != nil { return nil, err } if ds == nil { // Dataset doesn't exist so create it c.logger.Debug("creating dependent count dataset") - ds, err = c.b.CreateDataset(ctx, datasetName) + ds, err = c.b.CreateDataset(ctx, c.datasetName) if err != nil { return nil, err } diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index b56c30cd..1c3d1bd3 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -30,9 +30,11 @@ import ( const defaultLogLevel = log.InfoLevel var ( - gcpProjectFlag = flag.String("gcp-project", "", "the Google Cloud Project to use. Required for deps.dev data collection.") - workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") - logLevel log.Level + gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") + depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") + depsdevDatasetFlag = flag.String("depsdev-dataset", depsdev.DefaultDatasetName, "the BigQuery dataset name to use.") + workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") + logLevel log.Level ) func init() { @@ -165,21 +167,18 @@ func main() { collector.Register(&github.IssuesCollector{}) collector.Register(githubmentions.NewCollector(ghClient)) - // Register the deps.dev collector IFF there is a GCP Project ID set. - if *gcpProjectFlag == "" { - logger.Warn("No GCP Project ID set. Skipping deps.dev signal collection") + if *depsdevDisableFlag { + // deps.dev collection has been disabled, so skip it. + logger.Warn("deps.dev signal collection is disabled.") } else { - ddcollector, err := depsdev.NewCollector(ctx, logger, *gcpProjectFlag) + ddcollector, err := depsdev.NewCollector(ctx, logger, *gcpProjectFlag, *depsdevDatasetFlag) if err != nil { logger.WithFields(log.Fields{ - "error": err, - "gcp_project_id": *gcpProjectFlag, + "error": err, }).Error("Failed to create deps.dev collector") os.Exit(2) } - logger.WithFields(log.Fields{ - "gcp_project_id": *gcpProjectFlag, - }).Info("deps.dev signal collector enabled") + logger.Info("deps.dev signal collector enabled") collector.Register(ddcollector) } From aa27b873e7bc9766e5672fce99afb47f26a04afd Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 22 Jul 2022 09:31:45 +1000 Subject: [PATCH 075/172] Add a README for the collect_signals cmd. (#148) * Add a README for the collect_signals cmd. * Minor tweaks to the collect_signals doc. - fix a missing gcloud login - add --update-adc to gcloud login - add some missing steps to restart docs --- cmd/collect_signals/README.md | 209 ++++++++++++++++++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 cmd/collect_signals/README.md diff --git a/cmd/collect_signals/README.md b/cmd/collect_signals/README.md new file mode 100644 index 00000000..c6377775 --- /dev/null +++ b/cmd/collect_signals/README.md @@ -0,0 +1,209 @@ +# Signal Collector + +This tool is used to collect signal data for a set of project repositories for +generating a criticality score. + +The input of this tool could by the output of the `enumerate_github` tool. + +The output of this tool is used as an input for the `scorer` tool, or for input +into a data analysis system such as BigQuery. + +## Example + +```shell +$ export GITHUB_TOKEN=ghp_x # Personal Access Token Goes Here +$ gcloud login --update-adc # Sign-in to GCP +$ collect_signals \ + -workers=1 \ + github_projects.txt \ + signals.csv +``` + +## Install + +```shell +$ go install github.com/ossf/criticality_score/cmd/collect_signals +``` + +## Usage + +```shell +$ collect_signals [FLAGS]... IN_FILE... OUT_FILE +``` + +Project repository URLs are read from each `IN_FILE` specified. If `-` is passed +in as an `IN_FILE` URLs will read from STDIN, along with any other files specified. + +Results are written in CSV format to `OUT_FILE`. If `OUT_FILE` is `-` the +results will be written to STDOUT. + +`FLAGS` are optional. See below for documentation. + +### Authentication + +`collect_signals` requires authentication to GitHub, and optionally Google Cloud Platform to run. + +#### GitHub Authentication + +A comma delimited environment variable with one or more GitHub Personal Access +Tokens must be set + +Supported environment variables are `GITHUB_AUTH_TOKEN`, `GITHUB_TOKEN`, +`GH_TOKEN`, or `GH_AUTH_TOKEN`. + +Example: + +```shell +$ export GITHUB_TOKEN=ghp_abc,ghp_123 +``` + +#### GCP Authentication + +BigQuery access requires the "BigQuery User" (`roles/bigquery.user`) role added +to the account used, or be an "Owner". + +##### Option 1: `gcloud login` + +This option is useful during development. Run `gcloud login --update-adc` to +login to GCP and prepare application default credentials. + +##### Option 2: GCE Service Worker + +If running on a GCE instance a service worker will be associated with the +machine. + +Simply ensure the service worker is added to the "BigQuery User" role. + +##### Option 3: Custom Service Worker + +A custom service worker is ideal for limiting access to GCP resources. + +One can be created through the console or via `gcloud` on the command line. + +For example: + +```shell +$ # Create the service worker account +$ gcloud iam service-accounts create [SERVICE-ACCOUNT-ID] +$ # Add the service worker to the "BigQuery User" role +$ gcloud projects add-iam-policy-binding [PROJECT-ID] --member="serviceAccount:[SERVICE-ACCOUNT-ID]@[PROJECT-ID].iam.gserviceaccount.com" --role=roles/bigquery.user +$ # Generate a credentials file for the service worker +$ gcloud iam service-accounts keys create [FILENAME].json --iam-account=[SERVICE-ACCOUNT-ID@[PROJECT-ID].iam.gserviceaccount.com +``` + +To use the service worker account the json credential file needs to be passed +in through the `GOOGLE_APPLICATION_CREDENTIALS` environment variable. + +Example: + +```shell +$ export GOOGLE_APPLICATION_CREDENTIALS=[FILENAME].json +``` + +See more on GCP +[service account docs](https://cloud.google.com/iam/docs/creating-managing-service-accounts). + +### Flags + +#### Output flags + +- `-append` appends output to `FILE` if it already exists. +- `-force` overwrites `FILE` if it already exists and `-append` is not set. + +If `FILE` exists and neither `-append` nor `-force` is set the command will fail. + +#### Google Cloud Platform flags + +- `-gcp-project-id string` the Google Cloud Project ID to use. Auto-detects by default. + +#### deps.dev Collection Flags + +- `-depsdev-disable` disables the collection of signals from deps.dev. +- `-depsdev-dataset string` the BigQuery dataset name to use. Default is `depsdev_analysis`. + +#### Misc flags + +- `-log level` set the level of logging. Can be `debug`, `info` (default), `warn` or `error`. +- `-workers int` the total number of concurrent workers to use. Default is `1`. +- `-help` displays help text. + +## Q&A + +### Q: How long does it take? + +It takes ~2.5 seconds per repository on a fast computer with excellent internet +access. + +From experience, if no rate limits are hit, a single worker can collect about +1400 repositories in an hour. + +### Q: How many workers should I use? + +Generally, use 1 worker per one or two Personal Access Tokens. + +On a fast computer with excellent internet access, a single worker can consume +the quota for a single token in about 30-40 minutes. + +### Q: Any tips on making it run fast and reliable? + +1. Spin up a compute instance in GCE with lots of RAM and fast network: + - Uses GCP's fast/reliable internet connectivity. + - Reduces latency and costs for querying BigQuery data (and perhaps + GitHub's data too). + - Prevents downtime due to local IT failures. +1. Shard the input repository list and run multiple instances on different + hosts with different GitHub tokens: + - Ensures work progresses even if one instance stops. + - Provides additional compute and network resources. + +### Q: How do I restart after a failure? + +If running with a single worker this process is fairly straightforward. + +1. Copy the input repository list file to a new file to edit. +1. Open the new file in an editor (note: it may be very large). +1. `tail -25` the output csv file to view the last entries. +1. In the editor, find the entry that corresponds to the last csv entry. + - If running with a single worker: delete this repository url and *all* + repository urls above it. + - If running with multiple workers: manually delete repository urls that + correspond to entries in the output csv until there are no unprocessed + repository urls interleaving processed urls. Delete the remaining urls + above the unprocessed urls. +1. Restart `collect_signals`: + - Use the new file as the input. + - Either use a new file as the output, or specify `-append`. + +*Note:* when correlating URLs it is possible that the repository has been +renamed. + +### Q: How much will GCP usage cost? + +deps.dev support is designed to work within the free pricing tier for GCP. + +A single BigQuery query of 3Gb data is executed once, with the resulting table +used for subsequent queries. + +Network transit costs should be small enough to also sit within the free tier. + +A free GCE instance could be used to reduce network transit costs, but may slow +down the collection. + +## Development + +Rather than installing the binary, use `go run` to run the command. + +For example: + +```shell +$ go run ./cmd/collect_signals [FLAGS]... IN_FILE... OUT_FILE +``` + +Pass in a single repo using echo to quickly test signal collection, for example: + +```shell +$ echo "https://github.com/django/django" | \ + go run ./cmd/collect_signals \ + -log=debug \ + - - +``` \ No newline at end of file From 31fb2b1c773ed5da86c6bfa6974870728dd1ce10 Mon Sep 17 00:00:00 2001 From: Azeem Shaikh Date: Mon, 1 Aug 2022 21:59:10 -0400 Subject: [PATCH 076/172] =?UTF-8?q?=E2=9C=A8=20Enable=20Scorecard=20badge?= =?UTF-8?q?=20(#155)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Enable Scorecard badge Signed-off-by: Azeem Shaikh * Add badge to README Signed-off-by: Azeem Shaikh --- .github/workflows/scorecards.yml | 45 ++++++++++++++++++++++++++++++++ README.md | 2 ++ 2 files changed, 47 insertions(+) create mode 100644 .github/workflows/scorecards.yml diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml new file mode 100644 index 00000000..225a7238 --- /dev/null +++ b/.github/workflows/scorecards.yml @@ -0,0 +1,45 @@ +name: OSSF Scorecard +on: + push: + # Only the default branch is supported. + branches: + - main + schedule: + # Weekly on Saturdays. + - cron: '30 1 * * 6' + +permissions: read-all + +jobs: + analysis: + name: Scorecard analysis + runs-on: ubuntu-latest + permissions: + security-events: write + id-token: write + steps: + - name: "Checkout code" + uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + - name: "Run analysis" + uses: ossf/scorecard-action@3155d134e59d8f47261b1ae9d143034c69572227 # v2.0.0-beta.1 + with: + results_file: results.sarif + results_format: sarif + repo_token: ${{ secrets.GITHUB_TOKEN }} + # Publish the results for public repositories to enable scorecard badges. For more details, see + # https://github.com/ossf/scorecard-action#publishing-results. + # For private repositories, `publish_results` will automatically be set to `false`, regardless + # of the value entered here. + publish_results: true + # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts + # Optional. + - name: "Upload artifact" + uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 + - name: "Upload SARIF results" + uses: github/codeql-action/upload-sarif@f5d822707ee6e8fb81b04a5c0040b736da22e587 # v1 + with: + sarif_file: results.sarif diff --git a/README.md b/README.md index 179dfe44..99cbd5a7 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # Open Source Project Criticality Score (Beta) +[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/ossf/criticality_score/badge)](https://api.securityscorecards.dev/projects/github.com/ossf/criticality_score) + This project is maintained by members of the [Securing Critical Projects WG](https://github.com/ossf/wg-securing-critical-projects). From 1a1ac42894eaa0561b68fc538027cbd76619139b Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 3 Aug 2022 10:11:58 +1000 Subject: [PATCH 077/172] Fix a bunch of minor issues. (#156) - "zapfian" should actually be "zipfian" - Some minor README tweak to a headings - Tweak the help text for the scorer's -config flag to indicate that it is required. - Clean up some extraneous comments --- cmd/enumerate_github/README.md | 2 +- cmd/scorer/algorithm/distribution.go | 2 +- cmd/scorer/algorithm/value.go | 4 ---- cmd/scorer/main.go | 4 ++-- config/scorer/original_pike.yml | 20 ++++++++++---------- config/scorer/pike_depsdev.yml | 24 ++++++++++++------------ 6 files changed, 26 insertions(+), 30 deletions(-) diff --git a/cmd/enumerate_github/README.md b/cmd/enumerate_github/README.md index f61869da..953fed80 100644 --- a/cmd/enumerate_github/README.md +++ b/cmd/enumerate_github/README.md @@ -75,7 +75,7 @@ If `FILE` exists and neither `-append` nor `-force` is set the command will fail to `5`. A an overlap is used to avoid missing repositories whose star count changes during enumeration. -#### Misc Flags +#### Misc flags - `-log level` set the level of logging. Can be `debug`, `info` (default), `warn` or `error`. - `-workers int` the total number of concurrent workers to use. Default is `1`. diff --git a/cmd/scorer/algorithm/distribution.go b/cmd/scorer/algorithm/distribution.go index 5ce71b87..99e855c8 100644 --- a/cmd/scorer/algorithm/distribution.go +++ b/cmd/scorer/algorithm/distribution.go @@ -20,7 +20,7 @@ func (d *Distribution) Normalize(v float64) float64 { var ( normalizationFuncs = map[string]func(float64) float64{ "linear": func(v float64) float64 { return v }, - "zapfian": func(v float64) float64 { return math.Log(1 + v) }, + "zipfian": func(v float64) float64 { return math.Log(1 + v) }, } DefaultDistributionName = "linear" ) diff --git a/cmd/scorer/algorithm/value.go b/cmd/scorer/algorithm/value.go index dfe4c2cc..b5435022 100644 --- a/cmd/scorer/algorithm/value.go +++ b/cmd/scorer/algorithm/value.go @@ -55,7 +55,3 @@ func (cv *ConditionalValue) Value(fields map[string]float64) (float64, bool) { return 0, false } } - -// Condition struct { Eval(fields map[string]float64) bool } -// Not(Condition) Condition -// Exists(Field) Condition diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index 05c00b0c..b7979f79 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -13,7 +13,7 @@ // legacy.created_since: // weight: 1 // upper: 120 -// distribution: zapfian +// distribution: zipfian // // The raw signals, along with the score, are returning in the output. package main @@ -39,7 +39,7 @@ import ( const defaultLogLevel = log.InfoLevel var ( - configFlag = flag.String("config", "", "the filename of the config") + configFlag = flag.String("config", "", "the filename of the config (required)") columnNameFlag = flag.String("column", "", "the name of the output column") logLevel log.Level ) diff --git a/config/scorer/original_pike.yml b/config/scorer/original_pike.yml index a080cdb0..2f52e812 100644 --- a/config/scorer/original_pike.yml +++ b/config/scorer/original_pike.yml @@ -7,59 +7,59 @@ inputs: weight: 1 bounds: upper: 120 - distribution: zapfian + distribution: zipfian - field: legacy.updated_since weight: 1 bounds: upper: 120 smaller_is_better: yes - distribution: zapfian + distribution: zipfian - field: legacy.contributor_count weight: 2 bounds: upper: 5000 - distribution: zapfian + distribution: zipfian - field: legacy.org_count weight: 1 bounds: upper: 10 - distribution: zapfian + distribution: zipfian - field: legacy.commit_frequency weight: 1 bounds: upper: 1000 - distribution: zapfian + distribution: zipfian - field: legacy.recent_release_count weight: 0.5 bounds: upper: 26 - distribution: zapfian + distribution: zipfian - field: legacy.updated_issues_count weight: 0.5 bounds: upper: 5000 - distribution: zapfian + distribution: zipfian - field: legacy.closed_issues_count weight: 0.5 bounds: upper: 5000 - distribution: zapfian + distribution: zipfian - field: legacy.issue_comment_frequency weight: 1 bounds: upper: 15 - distribution: zapfian + distribution: zipfian - field: legacy.github_mention_count weight: 2 bounds: upper: 500000 - distribution: zapfian + distribution: zipfian diff --git a/config/scorer/pike_depsdev.yml b/config/scorer/pike_depsdev.yml index d7b7933a..b6e6ab0b 100644 --- a/config/scorer/pike_depsdev.yml +++ b/config/scorer/pike_depsdev.yml @@ -5,56 +5,56 @@ inputs: weight: 1 bounds: upper: 120 - distribution: zapfian + distribution: zipfian - field: legacy.updated_since weight: 1 bounds: upper: 120 smaller_is_better: yes - distribution: zapfian + distribution: zipfian - field: legacy.contributor_count weight: 2 bounds: upper: 5000 - distribution: zapfian + distribution: zipfian - field: legacy.org_count weight: 1 bounds: upper: 10 - distribution: zapfian + distribution: zipfian - field: legacy.commit_frequency weight: 1 bounds: upper: 1000 - distribution: zapfian + distribution: zipfian - field: legacy.recent_release_count weight: 0.5 bounds: upper: 26 - distribution: zapfian + distribution: zipfian - field: legacy.updated_issues_count weight: 0.5 bounds: upper: 5000 - distribution: zapfian + distribution: zipfian - field: legacy.closed_issues_count weight: 0.5 bounds: upper: 5000 - distribution: zapfian + distribution: zipfian - field: legacy.issue_comment_frequency weight: 1 bounds: upper: 15 - distribution: zapfian + distribution: zipfian # If deps.dev dependenct count doesn't exist we use this configuration # for the GitHub search mention count. @@ -65,7 +65,7 @@ inputs: condition: not: field_exists: "depsdev.dependent_count" - distribution: zapfian + distribution: zipfian # If deps.dev dependent count *does* exist we lower the importance of # the GitHub search mention count. @@ -75,10 +75,10 @@ inputs: upper: 500000 condition: field_exists: "depsdev.dependent_count" - distribution: zapfian + distribution: zipfian - field: depsdev.dependent_count weight: 4 bounds: upper: 200000 - distribution: zapfian + distribution: zipfian From 440949c4df15157c6a3b5ea47eaf9d2413d47703 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 3 Aug 2022 13:25:27 +1000 Subject: [PATCH 078/172] Add a README for the scorer tool. (#157) --- cmd/scorer/README.md | 143 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 cmd/scorer/README.md diff --git a/cmd/scorer/README.md b/cmd/scorer/README.md new file mode 100644 index 00000000..bc0a6dad --- /dev/null +++ b/cmd/scorer/README.md @@ -0,0 +1,143 @@ +# Scoring Tool + +This tool is used to calculate a criticality score based on raw signals +collected across a set of projects. + +The input of this tool is usually the output of the `collect_signals` tool. + +## Example + +```shell +$ scorer \ + -config config/scorer/original_pike.yml \ + raw_signals.txt \ + scored_signals.txt +``` + +## Install + +```shell +$ go install github.com/ossf/criticality_score/cmd/scorer +``` + +## Usage + +```shell +$ scorer [FLAGS]... IN_FILE OUT_FILE +``` + +Raw signals are read as CSV from `IN_FILE`. If `-` is passed in for `IN_FILE` +raw signal data will read from STDIN rather than a file. + +Results are re-written in CSV format to `OUT_FILE`. If `OUT_FILE` is `-` the +results will be written to STDOUT. Results are sorted in descending score order. + +The `-config` flag is required. All other `FLAGS` are optional. +See below for documentation. + +### Flags + +#### Output flags + +- `-append` appends output to `OUT_FILE` if it already exists. +- `-force` overwrites `OUT_FILE` if it already exists and `-append` is not set. + +If `OUT_FILE` exists and neither `-append` nor `-force` is set the command will +fail. + +#### Scoring flags + +- `-config string` the name of a YAML config file to use for calculating the + score. Required. +- `-column string` the name of the column to store the score in. Defaults to + the name of the config file with `_score` appended (e.g. `config.yml` becomes + `config_score`). + +#### Misc flags + +- `-log level` set the level of logging. Can be `debug`, `info` (default), + `warn` or `error`. +- `-help` displays help text. + +## Config file format + +```yaml +# The algorithm used to combine the inputs together. +# Currently only "weighted_arithmetic_mean" is supported. +algorithm: weighted_arithmetic_mean + +# Inputs is an array of fields used as input for the algorithm. +inputs: + # The name of the field. This corresponds to the column name in the input + # CSV file. + # Required. + - field: namespace.field + + # The weight of the field. A higher weight means the value will have a + # bigger impact on the score. A weight of "0" means the input will have no + # impact on the score. + # Default: 1.0 + weight: 4.2 + + # Bounds defines the lower and upper bounds of values for this input, and + # whether or not larger or smaller values are considered "better" or more + # critical. + # Default: unset. + bounds: + # The lower bound as a float. Any values lower will be set to this value. + # Default: 0 (if bounds is set) + lower: 100 + # The upper bound as a float. Any values higher will be set to this + # value. + # Default: 0 (if bounds is set) + upper: 1000 + # A boolean indicating whether or not a small value is considered + # "better" or more critical. Can be "yes", or "no" + # Default: "no" or "false" (if bounds is set) + smaller_is_better: no + + # Condition will only include this input when calculating the score if and + # only if the condition returns true. Only the existance, or non-existance + # of value in another field can be tested currently. + # Only one key can be set under `condition` at a time. + # Default: unset (always true) + condition: + # Returns true if the specified field has a value. If the field is does + # not exist in the input CSV data the result will always be false. + # Must be used on its own. + field_exists: namespace.field2 + + # Not negates the condition. So a true value becomes false, and a false + # value becomes true. + # Must be used on its own. + not: + field_exists: namespace.field3 + + # The distribution is used to specify the type of statistical distribution + # for this field of data. This is used to help normalize the data so that + # it can be better combined. Valid values are "normal", "zipfian". + # Default: "normal" + distribution: normal +``` + +See +[config/scorer](https://github.com/ossf/criticality_score/tree/main/config/scorer) +for examples. + +## Development + +Rather than installing the binary, use `go run` to run the command. + +For example: + +```shell +$ go run ./cmd/scorer [FLAGS]... IN_FILE OUT_FILE +``` + +Use STDIN and STDOUT on a subset of data for fast iteration. For example: + +```shell +$ head -10 raw_signals.csv | go run ./cmd/scorer \ + -config config/scorer/original_pike.yml \ + - - +``` \ No newline at end of file From a97058c8a68265d43765354e61a72b5e44523030 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 18 Aug 2022 14:10:45 +1000 Subject: [PATCH 079/172] Add env vars that correspond with flags to support productionizing (#164) --- cmd/enumerate_github/main.go | 16 +++- internal/envflag/envflag.go | 60 +++++++++++++++ internal/envflag/envflag_test.go | 121 +++++++++++++++++++++++++++++++ 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 internal/envflag/envflag.go create mode 100644 internal/envflag/envflag_test.go diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index ba3e36c8..630ddd85 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -11,6 +11,7 @@ import ( "time" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" + "github.com/ossf/criticality_score/internal/envflag" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" @@ -39,6 +40,19 @@ var ( startDateFlag = dateFlag(epochDate) endDateFlag = dateFlag(time.Now().UTC().Truncate(oneDay)) logLevel log.Level + + // Maps environment variables to the flags they correspond to. + envFlagMap = envflag.Map{ + "CRITICALITY_SCORE_LOG_LEVEL": "log", + "CRITICALITY_SCORE_WORKERS": "workers", + "CRITICALITY_SCORE_START_DATE": "start", + "CRITICALITY_SCORE_END_DATE": "end", + "CRITICALITY_SCORE_OUTFILE_FORCE": "force", + "CRITICALITY_SCORE_QUERY": "query", + "CRITICALITY_SCORE_STARS_MIN": "min-stars", + "CRITICALITY_SCORE_STARS_OVERLAP": "start-overlap", + "CRITICALITY_SCORE_STARS_MIN_REQUIRED": "require-min-stars", + } ) // dateFlag implements the flag.Value interface to simplify the input and validation of @@ -109,7 +123,7 @@ func searchWorker(s *githubsearch.Searcher, logger *log.Entry, queries, results } func main() { - flag.Parse() + envflag.Parse(envFlagMap) logger := log.New() logger.SetLevel(logLevel) diff --git a/internal/envflag/envflag.go b/internal/envflag/envflag.go new file mode 100644 index 00000000..8c7ea109 --- /dev/null +++ b/internal/envflag/envflag.go @@ -0,0 +1,60 @@ +// Package envflag is a simple library for associating environment variables with flags. +// +// If using the default flag.CommandLine FlagSet, just call envflag.Parse() instead of flag.Parse(). +// +// Assign environment variables to flags using the Map type: +// +// var m := envflag.Map{ +// "MY_ENV_VAR": "my-flag" +// } +// +// If the flag and the environment variable is set the flag takes precidence. +package envflag + +import ( + "flag" + "os" +) + +type Map map[string]string + +func (m Map) Assign(fs *flag.FlagSet) error { + for env, f := range m { + if v, ok := os.LookupEnv(env); ok && v != "" { + err := fs.Set(f, v) + if err != nil { + return err + } + } + } + return nil +} + +func ParseFlagSet(fs *flag.FlagSet, args []string, m Map) error { + err := m.Assign(fs) + if err != nil { + switch fs.ErrorHandling() { + case flag.ContinueOnError: + return err + case flag.ExitOnError: + if err == flag.ErrHelp { + os.Exit(0) + } + os.Exit(2) + case flag.PanicOnError: + panic(err) + } + } + return fs.Parse(args) +} + +func Parse(m Map) { + if err := m.Assign(flag.CommandLine); err != nil { + // flag.CommandLine is set for ExitOnError + if err == flag.ErrHelp { + os.Exit(0) + } + os.Exit(2) + } + flag.Parse() +} diff --git a/internal/envflag/envflag_test.go b/internal/envflag/envflag_test.go new file mode 100644 index 00000000..7c7c86d8 --- /dev/null +++ b/internal/envflag/envflag_test.go @@ -0,0 +1,121 @@ +package envflag_test + +import ( + "flag" + "testing" + + "github.com/ossf/criticality_score/internal/envflag" +) + +func TestEnvVarSet(t *testing.T) { + expected := "value" + t.Setenv("TEST_ENV_VAR", expected) + + fs := flag.NewFlagSet("flagset", flag.ContinueOnError) + s := fs.String("test-flag", "default", "usage") + m := envflag.Map{ + "TEST_ENV_VAR": "test-flag", + } + err := envflag.ParseFlagSet(fs, []string{}, m) + if err != nil { + t.Errorf("Assign() = %v, want nil", err) + } + if *s != expected { + t.Errorf("flag = %v, want %v", *s, expected) + } +} + +func TestEnvVarMissing(t *testing.T) { + expected := "default" + + fs := flag.NewFlagSet("flagset", flag.ContinueOnError) + s := fs.String("test-flag", "default", "usage") + m := envflag.Map{ + "TEST_ENV_VAR": "test-flag", + } + err := envflag.ParseFlagSet(fs, []string{}, m) + if err != nil { + t.Errorf("Assign() = %v, want nil", err) + } + if *s != expected { + t.Errorf("flag = %v, want %v", *s, expected) + } +} + +func TestEnvVarEmpty(t *testing.T) { + expected := "default" + t.Setenv("TEST_ENV_VAR", "") + + fs := flag.NewFlagSet("flagset", flag.ContinueOnError) + s := fs.String("test-flag", "default", "usage") + m := envflag.Map{ + "TEST_ENV_VAR": "test-flag", + } + err := envflag.ParseFlagSet(fs, []string{}, m) + if err != nil { + t.Errorf("Assign() = %v, want nil", err) + } + if *s != expected { + t.Errorf("flag = %v, want %v", *s, expected) + } +} + +func TestEnvAndFlagSet(t *testing.T) { + expected := "another_value" + args := []string{"-test-flag=" + expected} + t.Setenv("TEST_ENV_VAR", "value") + + fs := flag.NewFlagSet("flagset", flag.ContinueOnError) + s := fs.String("test-flag", "default", "usage") + m := envflag.Map{ + "TEST_ENV_VAR": "test-flag", + } + err := envflag.ParseFlagSet(fs, args, m) + if err != nil { + t.Errorf("Assign() = %v, want nil", err) + } + if *s != expected { + t.Errorf("flag = %v, want %v", *s, expected) + } +} + +func TestMissingFlag(t *testing.T) { + t.Setenv("TEST_ENV_VAR", "value") + + fs := flag.NewFlagSet("flagset", flag.ContinueOnError) + m := envflag.Map{ + "TEST_ENV_VAR": "test-flag", + } + err := envflag.ParseFlagSet(fs, []string{}, m) + if err == nil { + t.Error("Assign() = nil, want an error") + } +} + +func TestInvalidValue(t *testing.T) { + t.Setenv("TEST_ENV_VAR", "not_a_number") + + fs := flag.NewFlagSet("flagset", flag.ContinueOnError) + fs.Int("test-flag", 42, "usage") + m := envflag.Map{ + "TEST_ENV_VAR": "test-flag", + } + err := envflag.ParseFlagSet(fs, []string{}, m) + if err == nil { + t.Error("Assign() = nil, want an error") + } +} + +func TestParse(t *testing.T) { + expected := "value" + t.Setenv("TEST_ENV_VAR", expected) + + s := flag.String("test-flag", "default", "usage") + m := envflag.Map{ + "TEST_ENV_VAR": "test-flag", + } + envflag.Parse(m) + if *s != expected { + t.Errorf("flag = %v, want %v", *s, expected) + } +} From 8e9160cf24f03b2cdfa6a40d180fafe163774113 Mon Sep 17 00:00:00 2001 From: Azeem Shaikh Date: Thu, 18 Aug 2022 23:21:54 -0400 Subject: [PATCH 080/172] Update scorecard-action to v2:alpha (#165) --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 225a7238..b889fedb 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -21,7 +21,7 @@ jobs: - name: "Checkout code" uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: "Run analysis" - uses: ossf/scorecard-action@3155d134e59d8f47261b1ae9d143034c69572227 # v2.0.0-beta.1 + uses: ossf/scorecard-action@08dd0cebb088ac0fd6364339b1b3b68b75041ea8 # v2.0.0-alpha.2 with: results_file: results.sarif results_format: sarif From 68281a02332c724771eb302514ad5e213908ab98 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 23 Aug 2022 12:04:20 +1000 Subject: [PATCH 081/172] Add blob storage support for output. (#166) This allows the tools to write direct to cloud storage. This supports productionization of the tools --- cmd/collect_signals/main.go | 2 +- cmd/enumerate_github/main.go | 4 +- cmd/scorer/main.go | 7 +- go.mod | 23 +++ go.sum | 323 ++++++++++++++++++++++++++++++- internal/outfile/outfile.go | 57 ++++-- internal/outfile/outfile_test.go | 37 +++- 7 files changed, 423 insertions(+), 30 deletions(-) diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 1c3d1bd3..bbfd7729 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -137,7 +137,7 @@ func main() { // Open the out-file for writing outFilename := flag.Args()[lastArg] - w, err := outfile.Open(outFilename) + w, err := outfile.Open(context.Background(), outFilename) if err != nil { logger.WithFields(log.Fields{ "error": err, diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 630ddd85..03c9a26e 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -50,7 +50,7 @@ var ( "CRITICALITY_SCORE_OUTFILE_FORCE": "force", "CRITICALITY_SCORE_QUERY": "query", "CRITICALITY_SCORE_STARS_MIN": "min-stars", - "CRITICALITY_SCORE_STARS_OVERLAP": "start-overlap", + "CRITICALITY_SCORE_STARS_OVERLAP": "star-overlap", "CRITICALITY_SCORE_STARS_MIN_REQUIRED": "require-min-stars", } ) @@ -156,7 +156,7 @@ func main() { }).Info("Preparing output file") // Open the output file - out, err := outfile.Open(outFilename) + out, err := outfile.Open(context.Background(), outFilename) if err != nil { // File failed to open logger.WithFields(log.Fields{ diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index b7979f79..f99689db 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -19,6 +19,7 @@ package main import ( + "context" "encoding/csv" "errors" "flag" @@ -133,7 +134,7 @@ func main() { } // Open the out-file for writing - f, err := outfile.Open(outFilename) + f, err := outfile.Open(context.Background(), outFilename) if err != nil { logger.WithFields(log.Fields{ "error": err, @@ -151,7 +152,7 @@ func main() { os.Exit(2) } - f, err = os.Open(*configFlag) + cf, err := os.Open(*configFlag) if err != nil { logger.WithFields(log.Fields{ "error": err, @@ -159,7 +160,7 @@ func main() { }).Error("Failed to open config file") os.Exit(2) } - c, err := LoadConfig(f) + c, err := LoadConfig(cf) if err != nil { logger.WithFields(log.Fields{ "error": err, diff --git a/go.mod b/go.mod index 62a0118a..1eb36321 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require ( github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 github.com/sirupsen/logrus v1.8.1 + gocloud.dev v0.26.0 google.golang.org/api v0.74.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -17,6 +18,25 @@ require ( cloud.google.com/go v0.100.2 // indirect cloud.google.com/go/compute v1.5.0 // indirect cloud.google.com/go/iam v0.3.0 // indirect + cloud.google.com/go/storage v1.22.0 // indirect + github.com/aws/aws-sdk-go v1.43.31 // indirect + github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect + github.com/aws/aws-sdk-go-v2/config v1.15.3 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.11.2 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect + github.com/aws/smithy-go v1.11.2 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -26,7 +46,10 @@ require ( github.com/google/go-cmp v0.5.8 // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/google/wire v0.5.0 // indirect github.com/googleapis/gax-go/v2 v2.3.0 // indirect + github.com/googleapis/go-type-adapters v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect github.com/stretchr/testify v1.7.1 // indirect go.opencensus.io v0.23.0 // indirect diff --git a/go.sum b/go.sum index eb60af09..7534a062 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,7 @@ cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmW cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.82.0/go.mod h1:vlKccHJGuFBFufnAnuB08dfEH9Y3H7dzDzRECFdC2TA= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= @@ -26,6 +27,7 @@ cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+Y cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= +cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -37,6 +39,7 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/bigquery v1.32.0 h1:0OMQYCp03Ff9B5OeVY8GGUlOC99s93bjM+c5xS0H5gs= cloud.google.com/go/bigquery v1.32.0/go.mod h1:hAfV1647X+/fGUqeVVdKW+HfYtT5UCjOZsuOydOSH4M= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= @@ -44,29 +47,121 @@ cloud.google.com/go/datacatalog v1.3.0 h1:3llKXv7cC1acsWjvWmG0NQQkYVSVgunMSfVk7h cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= +cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= +cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= +cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= +cloud.google.com/go/monitoring v1.4.0/go.mod h1:y6xnxfwI3hTFWOdkOaD7nfJVlwuC3/mS/5kvtT131p4= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= +cloud.google.com/go/secretmanager v1.3.0/go.mod h1:+oLTkouyiYiabAQNugCeTS3PAArGiMJuBqvJnJsyH+U= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= cloud.google.com/go/storage v1.22.0 h1:NUV0NNp9nkBuW66BFRLuMgldN60C57ET3dhbwLIYio8= cloud.google.com/go/storage v1.22.0/go.mod h1:GbaLEoMqbVm6sx3Z0R++gSiBlgMv6yUi2q1DeGFKQgE= +cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= +cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= +contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= +contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= +contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= +github.com/Azure/azure-amqp-common-go/v3 v3.2.2/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= +github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= +github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= +github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v59.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= +github.com/Azure/azure-service-bus-go v0.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= +github.com/Azure/azure-storage-blob-go v0.14.0 h1:1BCg74AmVdYwO3dlKwtFU1V0wU2PZdREkXvAmZJRUlM= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-amqp v0.16.4/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= +github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= +github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.17/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.9/go.mod h1:hg3/1yw0Bq87O3KvvnJoAh34/0zbP7SFizX/qN5JvjU= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= +github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= +github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= +github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= +github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= +github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go-v2 v1.16.2 h1:fqlCk6Iy3bnCumtrLz9r3mJ/2gUT0pJ0wLFVIdWh+JA= +github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 h1:SdK4Ppk5IzLs64ZMvr6MrSficMtjY2oS0WOORXTlxwU= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM= +github.com/aws/aws-sdk-go-v2/config v1.15.3 h1:5AlQD0jhVXlGzwo+VORKiUuogkG7pQcLJNzIzK7eodw= +github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= +github.com/aws/aws-sdk-go-v2/credentials v1.11.2 h1:RQQ5fzclAKJyY5TvF+fkjJEwzK4hnxQCLOu5JXzDmQo= +github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 h1:LWPg5zjHV9oz/myQr4wMs0gi4CjnDN/ILmyZUFYXZsU= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 h1:ir7iEq78s4txFGgwcLqD6q9IIPzTQNRJXulJd9h/zQo= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3/go.mod h1:0dHuD2HZZSiwfJSy1FO5bX1hQ1TxVV1QXXjpn3XUE44= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 h1:onz/VaaxZ7Z4V+WIN9Txly9XLTmoOh1oJ8XcAC3pako= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 h1:9stUQR/u2KXU6HkFJYlqnZEjBnbgrVbG6I5HN09xZh0= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 h1:by9P+oy3P/CwggN4ClnW2D4oL91QV7pBzBICi1chZvQ= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 h1:T4pFel53bkHjL2mMo+4DKE6r6AuoZnM0fg7k1/ratr4= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 h1:I0dcwWitE752hVSMrsLCxqNQ+UdEp3nACx2bYNMQq+k= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 h1:Gh1Gpyh01Yvn7ilO/b/hr01WgNpaszfbKMUgqM186xQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 h1:BKjwCJPnANbkwQ8vzSbaZDKawwagDubrH/z/c0X+kbQ= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3/go.mod h1:Bm/v2IaN6rZ+Op7zX+bOUMdL4fsrYZiD0dsjLhNKwZc= +github.com/aws/aws-sdk-go-v2/service/kms v1.16.3/go.mod h1:QuiHPBqlOFCi4LqdSskYYAWpQlx3PKmohy+rE2F+o5g= +github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 h1:rMPtwA7zzkSQZhhz9U3/SoIDz/NZ7Q+iRn4EIO8rSyU= +github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3/go.mod h1:g1qvDuRsJY+XghsV6zg00Z4KJ7DtFFCx8fJD2a491Ak= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4/go.mod h1:PJc8s+lxyU8rrre0/4a0pn2wgwiDvOEzoOjcJUBr67o= +github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw= +github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3/go.mod h1:skmQo0UPvsjsuYYSYMVmrPc1HWCbHUJyrCEp+ZaLzqM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1/go.mod h1:NR/xoKjdbRJ+qx0pMR4mI+N/H1I1ynHwXnO6FowXJc0= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 h1:frW4ikGcxfAEDfmQqWgMLp+F1n4nRo9sF39OcIb5BkQ= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 h1:cJGRyzCSVwZC7zZZ1xbx9m32UnrKydRYhOvcD1NYP9Q= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= +github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= +github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 h1:tXKVfhE7FcSkhkv0UwkLvPDeZ4kz6OXd0PKPlFqf81M= github.com/bradleyfalzon/ghinstallation/v2 v2.0.4/go.mod h1:B40qPqJxWE0jDZgOR1JmaMy+4AY1eBP+IByOvqyAKp0= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -81,10 +176,20 @@ github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWH github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= +github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -94,16 +199,39 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= +github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= +github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= +github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= +github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -161,12 +289,19 @@ github.com/google/go-github/v44 v44.1.0 h1:shWPaufgdhr+Ad4eo/pZv9ORTxFpsxPEPEuuX github.com/google/go-github/v44 v44.1.0/go.mod h1:iWn00mWcP6PRWHhXm0zuFJ8wbEjE5AGO5D5HXYM4zgw= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= -github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no= +github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE= +github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6AwLM6miiXUQwP1S+I9icmhk= +github.com/google/go-replayers/httpreplay v1.1.1 h1:H91sIMlt1NZzN7R+/ASswyouLJfW0WLW7fhyUFvDEkY= +github.com/google/go-replayers/httpreplay v1.1.1/go.mod h1:gN9GeLIs7l6NUoVaSSnv2RiqK1NiwAmD0MrKeC9IIks= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE= +github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/martian/v3 v3.2.1 h1:d8MncMlErDFTwQGBK1xhv026j9kqhvw1Qv9IbWT1VLQ= github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= +github.com/google/martian/v3 v3.3.2 h1:IqNFLAmvJOgVlpdEBiQbDc2EwKW77amAycfTuWKdfvw= +github.com/google/martian/v3 v3.3.2/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -178,11 +313,18 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= +github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= +github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -192,52 +334,142 @@ github.com/googleapis/gax-go/v2 v2.3.0 h1:nRJtk3y8Fm770D42QV6T90ZnvFZyk7agSo3Q+Z github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= +github.com/hanwen/go-fuse/v2 v2.1.0/go.mod h1:oRyA5eK+pvJyv5otpO/DgccS8y/RvYMaO00GgRLGryc= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= +github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= +github.com/jackc/pgconn v0.0.0-20190420214824-7e0022ef6ba3/go.mod h1:jkELnwuX+w9qN5YIfX0fl88Ehu4XC3keFuOJJk9pcnA= +github.com/jackc/pgconn v0.0.0-20190824142844-760dd75542eb/go.mod h1:lLjNuW/+OfW9/pnVKPazfWOgNfH2aPem8YQ7ilXGvJE= +github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsUgOEh9hBm+xYTstcNHg7UPMVJqRfQxq4s= +github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= +github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= +github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= +github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= +github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65/go.mod h1:5R2h2EEX+qri8jOWMbJCtaPWkrrNc7OHwsp2TCqp7ak= +github.com/jackc/pgpassfile v1.0.0/go.mod h1:CEx0iS5ambNFdcRtxPj5JhEz+xB6uRky5eyVu/W2HEg= +github.com/jackc/pgproto3 v1.1.0/go.mod h1:eR5FA3leWg7p9aeAqi37XOTgTIbkABlvcPB3E5rlc78= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190420180111-c116219b62db/go.mod h1:bhq50y+xrl9n5mRYyCBFKkpRVTLYJVWeCc+mEAI3yXA= +github.com/jackc/pgproto3/v2 v2.0.0-alpha1.0.20190609003834-432c2951c711/go.mod h1:uH0AWtUmuShn0bcesswc4aBTWGvw0cAxIJp+6OB//Wg= +github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= +github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= +github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= +github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= +github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= +github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= +github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= +github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= +github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= +github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= +github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= +github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= +github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= +github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= +github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 h1:Db6m7J/xaItRxVbesKIXwngw+Tr1IERv/LCnRBzhHvk= github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4/go.mod h1:PbooSR+65A6HA+eoJ7ICwek/muANHZsR08QV24tuiKA= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= +github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= +github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 h1:82EIpiGB79OIPgSGa63Oj4Ipf+YAX1c6A9qjmEYoRXc= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= +github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= +github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -247,12 +479,40 @@ go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= +go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= +go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= +go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= +go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= +go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +gocloud.dev v0.26.0 h1:4rM/SVL0lLs+rhC0Gmc+gt/82DBpb7nbpIZKXXnfMXg= +gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -290,6 +550,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -302,6 +563,8 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -325,6 +588,9 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= @@ -341,10 +607,12 @@ golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= @@ -361,19 +629,26 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -386,6 +661,7 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -398,6 +674,7 @@ golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -408,15 +685,21 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -432,21 +715,28 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -454,6 +744,7 @@ golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200103221440-774c71fcf114/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= @@ -483,6 +774,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -510,6 +803,7 @@ google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34q google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= +google.golang.org/api v0.46.0/go.mod h1:ceL4oozhkAiTID8XMmJBsIxID/9wMXJVVFXPg4ylg3I= google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= @@ -518,9 +812,15 @@ google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6 google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3lv+E= +google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= +google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.68.0/go.mod h1:sOM8pTpwgflXRhz+oC8H2Dr+UcbMqkPPWNJo88Q7TH8= +google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= @@ -574,7 +874,9 @@ google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= +google.golang.org/genproto v0.0.0-20210517163617-5e0236093d7a/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= @@ -589,18 +891,31 @@ google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEc google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210917145530-b395a37504d4/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210921142501-181ce0d877f6/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211008145708-270636b82663/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211018162055-cf77aa76bad2/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211028162531-8db9c33dc351/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220204002441-d6cc3cc0770e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= +google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9 h1:XGQ6tc+EnM35IAazg4y6AHmUg4oK8NXsXaILte1vRlk= @@ -655,8 +970,11 @@ gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8 gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= @@ -669,6 +987,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index a4be6bc3..7e79b7f0 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -1,9 +1,18 @@ package outfile import ( + "context" "flag" "fmt" + "io" + "net/url" "os" + + "gocloud.dev/blob" + _ "gocloud.dev/blob/fileblob" + _ "gocloud.dev/blob/gcsblob" + _ "gocloud.dev/blob/memblob" + _ "gocloud.dev/blob/s3blob" ) // fileOpener wraps a method for opening files. @@ -26,6 +35,7 @@ func (f fileOpenerFunc) Open(filename string, flags int, perm os.FileMode) (*os. type Opener struct { force bool append bool + forceFlag string fileOpener fileOpener Perm os.FileMode StdoutName string @@ -37,37 +47,56 @@ func CreateOpener(fs *flag.FlagSet, forceFlag string, appendFlag string, fileHel Perm: 0666, StdoutName: "-", fileOpener: fileOpenerFunc(os.OpenFile), + forceFlag: forceFlag, } fs.BoolVar(&(o.force), forceFlag, false, fmt.Sprintf("overwrites %s if it already exists and -%s is not set.", fileHelpName, appendFlag)) fs.BoolVar(&(o.append), appendFlag, false, fmt.Sprintf("appends to %s if it already exists.", fileHelpName)) return o } -func (o *Opener) openInternal(filename string, extraFlags int) (*os.File, error) { +func (o *Opener) openFile(filename string, extraFlags int) (io.WriteCloser, error) { return o.fileOpener.Open(filename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|extraFlags, o.Perm) } +func (o *Opener) openBlobStore(ctx context.Context, bucket, prefix string) (io.WriteCloser, error) { + if o.append || !o.force { + return nil, fmt.Errorf("blob store must use -%s flag", o.forceFlag) + } + b, err := blob.OpenBucket(ctx, bucket) + if err != nil { + return nil, fmt.Errorf("failed to opening %s: %w", bucket, err) + } + w, err := b.NewWriter(ctx, prefix, nil) + if err != nil { + return nil, fmt.Errorf("failed creating writer for %s/%s: %w", bucket, prefix, err) + } + return w, nil +} + // Open opens and returns a file for output with the given filename. // // If filename is equal to o.StdoutName, os.Stdout will be used. // If filename does not exist, it will be created with the mode set in o.Perm. // If filename does exist, the behavior of this function will depend on the // flags: -// - if appendFlag is set on the command line the existing file will be -// appended to. -// - if forceFlag is set on the command line the existing file will be -// truncated. -// - if neither forceFlag nor appendFlag are set an error will be -// returned. -func (o *Opener) Open(filename string) (f *os.File, err error) { +// +// - if appendFlag is set on the command line the existing file will be +// appended to. +// - if forceFlag is set on the command line the existing file will be +// truncated. +// - if neither forceFlag nor appendFlag are set an error will be +// returned. +func (o *Opener) Open(ctx context.Context, filename string) (wc io.WriteCloser, err error) { if o.StdoutName != "" && filename == o.StdoutName { - f = os.Stdout + wc = os.Stdout + } else if u, e := url.Parse(filename); e == nil && u.IsAbs() { + wc, err = o.openBlobStore(ctx, u.Scheme+"://"+u.Host, u.Path) } else if o.append { - f, err = o.openInternal(filename, os.O_APPEND) + wc, err = o.openFile(filename, os.O_APPEND) } else if o.force { - f, err = o.openInternal(filename, os.O_TRUNC) + wc, err = o.openFile(filename, os.O_TRUNC) } else { - f, err = o.openInternal(filename, os.O_EXCL) + wc, err = o.openFile(filename, os.O_EXCL) } return } @@ -81,6 +110,6 @@ func DefineFlags(fs *flag.FlagSet, forceFlag string, appendFlag string, fileHelp } // Open is a wrapper around Opener.Open for the default instance of Opener. -func Open(filename string) (*os.File, error) { - return defaultOpener.Open(filename) +func Open(ctx context.Context, filename string) (io.WriteCloser, error) { + return defaultOpener.Open(ctx, filename) } diff --git a/internal/outfile/outfile_test.go b/internal/outfile/outfile_test.go index f91f4382..b8ac38fd 100644 --- a/internal/outfile/outfile_test.go +++ b/internal/outfile/outfile_test.go @@ -1,6 +1,7 @@ package outfile import ( + "context" "errors" "flag" "os" @@ -59,16 +60,36 @@ func TestAppendFlagDefined(t *testing.T) { func TestOpenStdout(t *testing.T) { o := newTestOpener() - f, err := o.opener.Open("-stdout-") + f, err := o.opener.Open(context.Background(), "-stdout-") if err != nil { t.Fatalf("Open() == %v, want nil", err) } if f != os.Stdout { - n := "nil" - if f != nil { - n = f.Name() - } - t.Fatalf("Open() == %s, want %v", n, os.Stdout.Name()) + t.Fatal("Open() == not stdout, want stdout") + } +} + +func TestOpenBucketUrl(t *testing.T) { + o := newTestOpener() + o.flag.Parse([]string{"-force"}) + f, err := o.opener.Open(context.Background(), "mem://bucket/prefix") + if err != nil { + t.Fatalf("Open() == %v, want nil", err) + } + if o.lastOpen != nil { + t.Fatal("Open(...) called instead of bucket code") + } + if f == nil { + t.Fatal("Open() == nil, want io.WriterCloser") + } +} + +func TestOpenBucketUrlNoForceFlag(t *testing.T) { + o := newTestOpener() + o.flag.Parse([]string{}) + _, err := o.opener.Open(context.Background(), "mem://bucket/prefix") + if err == nil { + t.Fatalf("Open() == nil, want an error") } } @@ -106,7 +127,7 @@ func TestOpenFlagTest(t *testing.T) { t.Run(test.name, func(t *testing.T) { o := newTestOpener() o.flag.Parse(test.args) - f, err := o.opener.Open("path/to/file") + f, err := o.opener.Open(context.Background(), "path/to/file") if err != nil { t.Fatalf("Open() == %v, want nil", err) } @@ -123,7 +144,7 @@ func TestOpenFlagTest(t *testing.T) { o := newTestOpener() o.flag.Parse(test.args) o.openErr = errors.New("test error") - _, err := o.opener.Open("path/to/file") + _, err := o.opener.Open(context.Background(), "path/to/file") if err == nil { t.Fatalf("Open() is nil, want %v", o.openErr) } From d88a7d629edadf2cfa84b7246302a9d7f14235b8 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 23 Aug 2022 13:36:35 +1000 Subject: [PATCH 082/172] Add support for runID in the output filename. (#167) --- cmd/enumerate_github/main.go | 12 ++++++ go.mod | 28 ++++++------ go.sum | 84 +++++++++++++++++++++++++++++++----- 3 files changed, 101 insertions(+), 23 deletions(-) diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 03c9a26e..e2b2fffd 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -8,6 +8,7 @@ import ( "net/http" "os" "path" + "strings" "time" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" @@ -26,6 +27,8 @@ const ( reposPerPage = 100 oneDay = time.Hour * 24 defaultLogLevel = log.InfoLevel + runIDToken = "[[runid]]" + runIDDateFormat = "20060102-1504" ) var ( @@ -150,6 +153,15 @@ func main() { } outFilename := flag.Arg(0) + // Expand runIDToken into the runID inside the output file's name. + if strings.Contains(outFilename, runIDToken) { + runID := time.Now().UTC().Format(runIDDateFormat) + logger.WithFields(log.Fields{ + "run-id": runID, + }).Info("Using Run ID") + outFilename = strings.ReplaceAll(outFilename, runIDToken, runID) + } + // Print a helpful message indicating the configuration we're using. logger.WithFields(log.Fields{ "filename": outFilename, diff --git a/go.mod b/go.mod index 1eb36321..6f6dc5c8 100644 --- a/go.mod +++ b/go.mod @@ -10,15 +10,15 @@ require ( github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 github.com/sirupsen/logrus v1.8.1 gocloud.dev v0.26.0 - google.golang.org/api v0.74.0 + google.golang.org/api v0.88.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - cloud.google.com/go v0.100.2 // indirect - cloud.google.com/go/compute v1.5.0 // indirect + cloud.google.com/go v0.102.1 // indirect + cloud.google.com/go/compute v1.7.0 // indirect cloud.google.com/go/iam v0.3.0 // indirect - cloud.google.com/go/storage v1.22.0 // indirect + cloud.google.com/go/storage v1.25.0 // indirect github.com/aws/aws-sdk-go v1.43.31 // indirect github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect @@ -46,21 +46,23 @@ require ( github.com/google/go-cmp v0.5.8 // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect + github.com/google/uuid v1.3.0 // indirect github.com/google/wire v0.5.0 // indirect - github.com/googleapis/gax-go/v2 v2.3.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect + github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/googleapis/go-type-adapters v1.0.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect - github.com/stretchr/testify v1.7.1 // indirect + github.com/stretchr/testify v1.8.0 // indirect go.opencensus.io v0.23.0 // indirect - golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 // indirect - golang.org/x/net v0.0.0-20220401154927-543a649e0bdd // indirect - golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a // indirect - golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f // indirect + golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect + golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect + golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect + golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/text v0.3.7 // indirect - golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f // indirect + golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9 // indirect - google.golang.org/grpc v1.45.0 // indirect + google.golang.org/genproto v0.0.0-20220720214146-176da50484ac // indirect + google.golang.org/grpc v1.48.0 // indirect google.golang.org/protobuf v1.28.0 // indirect ) diff --git a/go.sum b/go.sum index 7534a062..167598dd 100644 --- a/go.sum +++ b/go.sum @@ -30,6 +30,9 @@ cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2Z cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -41,8 +44,12 @@ cloud.google.com/go/bigquery v1.32.0/go.mod h1:hAfV1647X+/fGUqeVVdKW+HfYtT5UCjOZ cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= -cloud.google.com/go/compute v1.5.0 h1:b1zWmYuuHz7gO9kDcM/EpHGr06UgsYNRpNJzI2kFiLM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/datacatalog v1.3.0 h1:3llKXv7cC1acsWjvWmG0NQQkYVSVgunMSfVk7h6zz8Q= cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= @@ -70,6 +77,9 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9 cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= cloud.google.com/go/storage v1.22.0 h1:NUV0NNp9nkBuW66BFRLuMgldN60C57ET3dhbwLIYio8= cloud.google.com/go/storage v1.22.0/go.mod h1:GbaLEoMqbVm6sx3Z0R++gSiBlgMv6yUi2q1DeGFKQgE= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.25.0 h1:D2Dn0PslpK7Z3B2AvuUHyIC762bDbGJdlmQlCBR71os= +cloud.google.com/go/storage v1.25.0/go.mod h1:Qys4JU+jeup3QnuKKAosWuxrD95C4MSqxfVDnSirDsI= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= @@ -175,6 +185,7 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -198,6 +209,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -325,6 +337,9 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= @@ -332,6 +347,8 @@ github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0 github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0 h1:nRJtk3y8Fm770D42QV6T90ZnvFZyk7agSo3Q+Z9p3WI= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -453,14 +470,16 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -513,8 +532,9 @@ golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29 h1:tkVvjkPTB7pnW3jnid7kNyAMPVWllTNOf/qKDze4p9o= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= +golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -594,8 +614,13 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220401154927-543a649e0bdd h1:zYlwaUHTmxuf6H7hwO2dgwqozQmH7zf4x+/qql4oVWc= golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -615,8 +640,12 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a h1:qfl7ob3DIEs3Ml9oLuPwY2N04gymzAW04WsUQHIClgM= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -628,6 +657,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -697,8 +727,15 @@ golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f h1:rlezHXNlxYWvBCzNses9Dlc7nGFaNMJeqLolcmQSSZY= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -780,8 +817,11 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f h1:GGU+dLjvlC3qDwqYgL6UgRmHXhOOgns0bZu2Ty5mm6U= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -823,8 +863,14 @@ google.golang.org/api v0.68.0/go.mod h1:sOM8pTpwgflXRhz+oC8H2Dr+UcbMqkPPWNJo88Q7 google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= -google.golang.org/api v0.74.0 h1:ExR2D+5TYIrMphWgs5JCgwRhEDlPDXXrLwHHMgPHTXE= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0 h1:0AYh/ae6l9TDUvIQrDw5QRpM100P6oHgD+o3dYHMzJg= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.88.0 h1:MPwxQRqpyskYhr2iNyfsQ8R06eeyhe7UEuR30p136ZQ= +google.golang.org/api v0.88.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -918,8 +964,21 @@ google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2I google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9 h1:XGQ6tc+EnM35IAazg4y6AHmUg4oK8NXsXaILte1vRlk= google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220720214146-176da50484ac h1:EOa+Yrhx1C0O+4pHeXeWrCwdI0tWI6IfUU56Vebs9wQ= +google.golang.org/genproto v0.0.0-20220720214146-176da50484ac/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -947,8 +1006,13 @@ google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.45.0 h1:NEpgUqV3Z+ZjkqMsxMg11IaDrXY4RY6CQukSGK0uI1M= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= From 325d58b5888d00fb2598f1fc017384d5149dc0dc Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 23 Aug 2022 16:53:38 +1000 Subject: [PATCH 083/172] Allow options to be present in the URL query string. (#168) This allows the usage of mimio as s3 storage. --- internal/outfile/outfile.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index 7e79b7f0..b3f4cd39 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -58,10 +58,17 @@ func (o *Opener) openFile(filename string, extraFlags int) (io.WriteCloser, erro return o.fileOpener.Open(filename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|extraFlags, o.Perm) } -func (o *Opener) openBlobStore(ctx context.Context, bucket, prefix string) (io.WriteCloser, error) { +func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, error) { if o.append || !o.force { return nil, fmt.Errorf("blob store must use -%s flag", o.forceFlag) } + + // Seperate the path from the URL as options may be present in the query + // string. + prefix := u.Path + u.Path = "" + bucket := u.String() + b, err := blob.OpenBucket(ctx, bucket) if err != nil { return nil, fmt.Errorf("failed to opening %s: %w", bucket, err) @@ -90,7 +97,7 @@ func (o *Opener) Open(ctx context.Context, filename string) (wc io.WriteCloser, if o.StdoutName != "" && filename == o.StdoutName { wc = os.Stdout } else if u, e := url.Parse(filename); e == nil && u.IsAbs() { - wc, err = o.openBlobStore(ctx, u.Scheme+"://"+u.Host, u.Path) + wc, err = o.openBlobStore(ctx, u) } else if o.append { wc, err = o.openFile(filename, os.O_APPEND) } else if o.force { From 8c6341d751969b4502e2796a4e106782c0b755e8 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 24 Aug 2022 13:21:54 +1000 Subject: [PATCH 084/172] Add a Dockerfile for productionizing the enumeration. (#169) --- cmd/enumerate_github/Dockerfile | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 cmd/enumerate_github/Dockerfile diff --git a/cmd/enumerate_github/Dockerfile b/cmd/enumerate_github/Dockerfile new file mode 100644 index 00000000..0c567be7 --- /dev/null +++ b/cmd/enumerate_github/Dockerfile @@ -0,0 +1,15 @@ +FROM golang@sha256:684d791f8fd1b28485ee32239d92cde7099d97c88c5ed2e955f65f4adcf35d0f AS base +WORKDIR /src +ENV CGO_ENABLED=0 +COPY go.* ./ +RUN go mod download +COPY . ./ + +FROM base AS enumerate_github +ARG TARGETOS +ARG TARGETARCH +RUN CGO_ENABLED=0 go build ./cmd/enumerate_github + +FROM gcr.io/distroless/base:nonroot@sha256:533c15ef2acb1d3b1cd4e58d8aa2740900cae8f579243a53c53a6e28bcac0684 +COPY --from=enumerate_github /src/enumerate_github ./enumerate_github +ENTRYPOINT ["./enumerate_github"] From 88aba46ab77e389dcfcab5e76d3dc7118e525edb Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 25 Aug 2022 13:32:32 +1000 Subject: [PATCH 085/172] Add copyright notice to all files (#172) --- cmd/collect_signals/collector/collector.go | 16 +++++++++++++++ cmd/collect_signals/collector/registry.go | 14 +++++++++++++ cmd/collect_signals/depsdev/bq.go | 14 +++++++++++++ cmd/collect_signals/depsdev/collector.go | 14 +++++++++++++ cmd/collect_signals/depsdev/dependents.go | 14 +++++++++++++ cmd/collect_signals/github/collector.go | 14 +++++++++++++ cmd/collect_signals/github/factory.go | 14 +++++++++++++ .../github/legacy/constants.go | 14 +++++++++++++ .../github/legacy/contributors.go | 14 +++++++++++++ cmd/collect_signals/github/legacy/created.go | 14 +++++++++++++ cmd/collect_signals/github/legacy/issues.go | 14 +++++++++++++ cmd/collect_signals/github/legacy/releases.go | 14 +++++++++++++ cmd/collect_signals/github/legacy/util.go | 14 +++++++++++++ cmd/collect_signals/github/queries.go | 14 +++++++++++++ cmd/collect_signals/github/repo.go | 14 +++++++++++++ .../githubmentions/collector.go | 14 +++++++++++++ cmd/collect_signals/main.go | 14 +++++++++++++ cmd/collect_signals/projectrepo/repo.go | 14 +++++++++++++ cmd/collect_signals/projectrepo/resolver.go | 14 +++++++++++++ cmd/collect_signals/result/csv.go | 14 +++++++++++++ cmd/collect_signals/result/emitter.go | 14 +++++++++++++ cmd/collect_signals/signal/issues.go | 14 +++++++++++++ cmd/collect_signals/signal/repo.go | 14 +++++++++++++ cmd/collect_signals/signal/signal.go | 20 ++++++++++++++++--- cmd/enumerate_github/Dockerfile | 14 +++++++++++++ cmd/enumerate_github/githubsearch/repos.go | 14 +++++++++++++ cmd/enumerate_github/githubsearch/search.go | 14 +++++++++++++ cmd/enumerate_github/main.go | 14 +++++++++++++ cmd/scorer/algorithm/algorithm.go | 14 +++++++++++++ cmd/scorer/algorithm/distribution.go | 14 +++++++++++++ cmd/scorer/algorithm/input.go | 14 +++++++++++++ cmd/scorer/algorithm/registry.go | 14 +++++++++++++ cmd/scorer/algorithm/value.go | 14 +++++++++++++ cmd/scorer/algorithm/wam/wam.go | 14 +++++++++++++ cmd/scorer/config.go | 14 +++++++++++++ cmd/scorer/main.go | 14 +++++++++++++ cmd/scorer/pq.go | 14 +++++++++++++ config/scorer/original_pike.yml | 14 +++++++++++++ config/scorer/pike_depsdev.yml | 14 +++++++++++++ internal/envflag/envflag.go | 14 +++++++++++++ internal/envflag/envflag_test.go | 14 +++++++++++++ internal/githubapi/batch.go | 14 +++++++++++++ internal/githubapi/client.go | 14 +++++++++++++ internal/githubapi/errors.go | 14 +++++++++++++ internal/githubapi/pagination/pagination.go | 14 +++++++++++++ internal/githubapi/roundtripper.go | 14 +++++++++++++ internal/githubapi/roundtripper_test.go | 14 +++++++++++++ internal/outfile/outfile.go | 14 +++++++++++++ internal/outfile/outfile_test.go | 14 +++++++++++++ internal/retry/request.go | 16 ++++++++++++++- internal/retry/request_test.go | 14 +++++++++++++ internal/textvarflag/flag_test.go | 14 +++++++++++++ internal/workerpool/workerpool.go | 14 +++++++++++++ internal/workerpool/workerpool_test.go | 14 +++++++++++++ 54 files changed, 762 insertions(+), 4 deletions(-) diff --git a/cmd/collect_signals/collector/collector.go b/cmd/collect_signals/collector/collector.go index 5bfb4f62..c214b6f5 100644 --- a/cmd/collect_signals/collector/collector.go +++ b/cmd/collect_signals/collector/collector.go @@ -1,3 +1,19 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +// Package collector defines the interface for signal collectors and a registry +// for using the collectors together. package collector import ( diff --git a/cmd/collect_signals/collector/registry.go b/cmd/collect_signals/collector/registry.go index 261a1d35..e006fa67 100644 --- a/cmd/collect_signals/collector/registry.go +++ b/cmd/collect_signals/collector/registry.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package collector import ( diff --git a/cmd/collect_signals/depsdev/bq.go b/cmd/collect_signals/depsdev/bq.go index 56f73eb4..b955bb12 100644 --- a/cmd/collect_signals/depsdev/bq.go +++ b/cmd/collect_signals/depsdev/bq.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package depsdev import ( diff --git a/cmd/collect_signals/depsdev/collector.go b/cmd/collect_signals/depsdev/collector.go index f7b49391..0f3339b9 100644 --- a/cmd/collect_signals/depsdev/collector.go +++ b/cmd/collect_signals/depsdev/collector.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package depsdev import ( diff --git a/cmd/collect_signals/depsdev/dependents.go b/cmd/collect_signals/depsdev/dependents.go index d296cd8d..34ae6281 100644 --- a/cmd/collect_signals/depsdev/dependents.go +++ b/cmd/collect_signals/depsdev/dependents.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package depsdev import ( diff --git a/cmd/collect_signals/github/collector.go b/cmd/collect_signals/github/collector.go index 0de22f21..4b821f36 100644 --- a/cmd/collect_signals/github/collector.go +++ b/cmd/collect_signals/github/collector.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package github import ( diff --git a/cmd/collect_signals/github/factory.go b/cmd/collect_signals/github/factory.go index b8d67b41..194fba92 100644 --- a/cmd/collect_signals/github/factory.go +++ b/cmd/collect_signals/github/factory.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package github import ( diff --git a/cmd/collect_signals/github/legacy/constants.go b/cmd/collect_signals/github/legacy/constants.go index 1d1c587c..c1ac8900 100644 --- a/cmd/collect_signals/github/legacy/constants.go +++ b/cmd/collect_signals/github/legacy/constants.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package legacy import ( diff --git a/cmd/collect_signals/github/legacy/contributors.go b/cmd/collect_signals/github/legacy/contributors.go index 9e9f6b1f..9d24b4af 100644 --- a/cmd/collect_signals/github/legacy/contributors.go +++ b/cmd/collect_signals/github/legacy/contributors.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package legacy import ( diff --git a/cmd/collect_signals/github/legacy/created.go b/cmd/collect_signals/github/legacy/created.go index 2ea44560..5bb712ad 100644 --- a/cmd/collect_signals/github/legacy/created.go +++ b/cmd/collect_signals/github/legacy/created.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package legacy import ( diff --git a/cmd/collect_signals/github/legacy/issues.go b/cmd/collect_signals/github/legacy/issues.go index f38b0d80..a9c03dde 100644 --- a/cmd/collect_signals/github/legacy/issues.go +++ b/cmd/collect_signals/github/legacy/issues.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package legacy import ( diff --git a/cmd/collect_signals/github/legacy/releases.go b/cmd/collect_signals/github/legacy/releases.go index 2186c648..faedc5ec 100644 --- a/cmd/collect_signals/github/legacy/releases.go +++ b/cmd/collect_signals/github/legacy/releases.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package legacy import ( diff --git a/cmd/collect_signals/github/legacy/util.go b/cmd/collect_signals/github/legacy/util.go index df39b989..9e936184 100644 --- a/cmd/collect_signals/github/legacy/util.go +++ b/cmd/collect_signals/github/legacy/util.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package legacy import ( diff --git a/cmd/collect_signals/github/queries.go b/cmd/collect_signals/github/queries.go index 10a9d723..2c0604bf 100644 --- a/cmd/collect_signals/github/queries.go +++ b/cmd/collect_signals/github/queries.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package github import ( diff --git a/cmd/collect_signals/github/repo.go b/cmd/collect_signals/github/repo.go index 988f8110..2a3aa40e 100644 --- a/cmd/collect_signals/github/repo.go +++ b/cmd/collect_signals/github/repo.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package github import ( diff --git a/cmd/collect_signals/githubmentions/collector.go b/cmd/collect_signals/githubmentions/collector.go index 88489ea9..6df82dfe 100644 --- a/cmd/collect_signals/githubmentions/collector.go +++ b/cmd/collect_signals/githubmentions/collector.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + // Package githubmentions provides a Collector that returns a Set for the // number of mentions a given repository has in commit messages as returned by // GitHub's search interface. diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index bbfd7729..4e23ad13 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package main import ( diff --git a/cmd/collect_signals/projectrepo/repo.go b/cmd/collect_signals/projectrepo/repo.go index 6967a5fc..0a377feb 100644 --- a/cmd/collect_signals/projectrepo/repo.go +++ b/cmd/collect_signals/projectrepo/repo.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package projectrepo import ( diff --git a/cmd/collect_signals/projectrepo/resolver.go b/cmd/collect_signals/projectrepo/resolver.go index 8a29002c..b092580c 100644 --- a/cmd/collect_signals/projectrepo/resolver.go +++ b/cmd/collect_signals/projectrepo/resolver.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package projectrepo import ( diff --git a/cmd/collect_signals/result/csv.go b/cmd/collect_signals/result/csv.go index c92d82cc..221bf30e 100644 --- a/cmd/collect_signals/result/csv.go +++ b/cmd/collect_signals/result/csv.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package result import ( diff --git a/cmd/collect_signals/result/emitter.go b/cmd/collect_signals/result/emitter.go index 0213a967..bc33eebd 100644 --- a/cmd/collect_signals/result/emitter.go +++ b/cmd/collect_signals/result/emitter.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package result import ( diff --git a/cmd/collect_signals/signal/issues.go b/cmd/collect_signals/signal/issues.go index 6154f863..f4c41030 100644 --- a/cmd/collect_signals/signal/issues.go +++ b/cmd/collect_signals/signal/issues.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package signal type IssuesSet struct { diff --git a/cmd/collect_signals/signal/repo.go b/cmd/collect_signals/signal/repo.go index c05fff81..a23833f9 100644 --- a/cmd/collect_signals/signal/repo.go +++ b/cmd/collect_signals/signal/repo.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package signal import "time" diff --git a/cmd/collect_signals/signal/signal.go b/cmd/collect_signals/signal/signal.go index c319f8ad..651916cc 100644 --- a/cmd/collect_signals/signal/signal.go +++ b/cmd/collect_signals/signal/signal.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package signal import ( @@ -98,9 +112,9 @@ func (s Field[T]) Value() any { // // This method is particularly useful when creating an new instance of a Set. // -// s = &FooSet{ -// myField: signal.Val("hello, world!") -// } +// s = &FooSet{ +// myField: signal.Val("hello, world!") +// } func Val[T SupportedType](v T) Field[T] { var f Field[T] f.Set(v) diff --git a/cmd/enumerate_github/Dockerfile b/cmd/enumerate_github/Dockerfile index 0c567be7..3056645c 100644 --- a/cmd/enumerate_github/Dockerfile +++ b/cmd/enumerate_github/Dockerfile @@ -1,3 +1,17 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + FROM golang@sha256:684d791f8fd1b28485ee32239d92cde7099d97c88c5ed2e955f65f4adcf35d0f AS base WORKDIR /src ENV CGO_ENABLED=0 diff --git a/cmd/enumerate_github/githubsearch/repos.go b/cmd/enumerate_github/githubsearch/repos.go index 0177fcf2..bd25a817 100644 --- a/cmd/enumerate_github/githubsearch/repos.go +++ b/cmd/enumerate_github/githubsearch/repos.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package githubsearch import ( diff --git a/cmd/enumerate_github/githubsearch/search.go b/cmd/enumerate_github/githubsearch/search.go index b693294a..1bd1f06c 100644 --- a/cmd/enumerate_github/githubsearch/search.go +++ b/cmd/enumerate_github/githubsearch/search.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package githubsearch import ( diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index e2b2fffd..d4831ca1 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package main import ( diff --git a/cmd/scorer/algorithm/algorithm.go b/cmd/scorer/algorithm/algorithm.go index 4f0fb717..f9470d9c 100644 --- a/cmd/scorer/algorithm/algorithm.go +++ b/cmd/scorer/algorithm/algorithm.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package algorithm type Algorithm interface { diff --git a/cmd/scorer/algorithm/distribution.go b/cmd/scorer/algorithm/distribution.go index 99e855c8..ccb31566 100644 --- a/cmd/scorer/algorithm/distribution.go +++ b/cmd/scorer/algorithm/distribution.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package algorithm import ( diff --git a/cmd/scorer/algorithm/input.go b/cmd/scorer/algorithm/input.go index 0586aa4e..a2214316 100644 --- a/cmd/scorer/algorithm/input.go +++ b/cmd/scorer/algorithm/input.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package algorithm type Bounds struct { diff --git a/cmd/scorer/algorithm/registry.go b/cmd/scorer/algorithm/registry.go index eba0910b..4b819eb2 100644 --- a/cmd/scorer/algorithm/registry.go +++ b/cmd/scorer/algorithm/registry.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package algorithm import "fmt" diff --git a/cmd/scorer/algorithm/value.go b/cmd/scorer/algorithm/value.go index b5435022..c8c80ef5 100644 --- a/cmd/scorer/algorithm/value.go +++ b/cmd/scorer/algorithm/value.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package algorithm type Value interface { diff --git a/cmd/scorer/algorithm/wam/wam.go b/cmd/scorer/algorithm/wam/wam.go index def88656..a545e194 100644 --- a/cmd/scorer/algorithm/wam/wam.go +++ b/cmd/scorer/algorithm/wam/wam.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + // The package wam implements the Weighted Arithmetic Mean, which forms the // basis of Rob Pike's criticality score algorithm as documented in // Quantifying_criticality_algorithm.pdf. diff --git a/cmd/scorer/config.go b/cmd/scorer/config.go index cd509d00..0f6e7d71 100644 --- a/cmd/scorer/config.go +++ b/cmd/scorer/config.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package main import ( diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index f99689db..8a598af9 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + // The scorer command is used for calculating the criticality score for signals // generated by the collect_signals command. // diff --git a/cmd/scorer/pq.go b/cmd/scorer/pq.go index 2ee54786..a8654823 100644 --- a/cmd/scorer/pq.go +++ b/cmd/scorer/pq.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package main import "container/heap" diff --git a/config/scorer/original_pike.yml b/config/scorer/original_pike.yml index 2f52e812..f2a1563d 100644 --- a/config/scorer/original_pike.yml +++ b/config/scorer/original_pike.yml @@ -1,3 +1,17 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + # The original set of weights defined for the criticality score project using # Rob Pike's algorithm as implemented in the original Python project. algorithm: weighted_arithmetic_mean diff --git a/config/scorer/pike_depsdev.yml b/config/scorer/pike_depsdev.yml index b6e6ab0b..a0a105a1 100644 --- a/config/scorer/pike_depsdev.yml +++ b/config/scorer/pike_depsdev.yml @@ -1,3 +1,17 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + algorithm: weighted_arithmetic_mean inputs: diff --git a/internal/envflag/envflag.go b/internal/envflag/envflag.go index 8c7ea109..357c64b1 100644 --- a/internal/envflag/envflag.go +++ b/internal/envflag/envflag.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + // Package envflag is a simple library for associating environment variables with flags. // // If using the default flag.CommandLine FlagSet, just call envflag.Parse() instead of flag.Parse(). diff --git a/internal/envflag/envflag_test.go b/internal/envflag/envflag_test.go index 7c7c86d8..19bdaee6 100644 --- a/internal/envflag/envflag_test.go +++ b/internal/envflag/envflag_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package envflag_test import ( diff --git a/internal/githubapi/batch.go b/internal/githubapi/batch.go index fa06a8e0..ab8d19fc 100644 --- a/internal/githubapi/batch.go +++ b/internal/githubapi/batch.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package githubapi import ( diff --git a/internal/githubapi/client.go b/internal/githubapi/client.go index bc72206e..850fad05 100644 --- a/internal/githubapi/client.go +++ b/internal/githubapi/client.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package githubapi import ( diff --git a/internal/githubapi/errors.go b/internal/githubapi/errors.go index c7d490cd..c403d79a 100644 --- a/internal/githubapi/errors.go +++ b/internal/githubapi/errors.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package githubapi import "github.com/google/go-github/v44/github" diff --git a/internal/githubapi/pagination/pagination.go b/internal/githubapi/pagination/pagination.go index ecf60696..7c4eb8d2 100644 --- a/internal/githubapi/pagination/pagination.go +++ b/internal/githubapi/pagination/pagination.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package pagination import ( diff --git a/internal/githubapi/roundtripper.go b/internal/githubapi/roundtripper.go index 43eb0675..89c15483 100644 --- a/internal/githubapi/roundtripper.go +++ b/internal/githubapi/roundtripper.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package githubapi import ( diff --git a/internal/githubapi/roundtripper_test.go b/internal/githubapi/roundtripper_test.go index 51f14a18..66f5f1b6 100644 --- a/internal/githubapi/roundtripper_test.go +++ b/internal/githubapi/roundtripper_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package githubapi import ( diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index b3f4cd39..2889aeb2 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package outfile import ( diff --git a/internal/outfile/outfile_test.go b/internal/outfile/outfile_test.go index b8ac38fd..e466c232 100644 --- a/internal/outfile/outfile_test.go +++ b/internal/outfile/outfile_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package outfile import ( diff --git a/internal/retry/request.go b/internal/retry/request.go index 6940fecf..967c8ed5 100644 --- a/internal/retry/request.go +++ b/internal/retry/request.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package retry import ( @@ -155,7 +169,7 @@ func NewRequest(r *http.Request, client func(*http.Request) (*http.Response, err // 2. Do returns an error // 3. The number of attempts exceeds MaxRetries // 4. No RetryStrategy was returned or only NoRetry, and RetryAfter() had no -// delay. +// delay. // // If Done returns true, Do must never be called again, otherwise Do will // return ErrorNoMoreAttempts. diff --git a/internal/retry/request_test.go b/internal/retry/request_test.go index ad36031f..d13009a7 100644 --- a/internal/retry/request_test.go +++ b/internal/retry/request_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package retry import ( diff --git a/internal/textvarflag/flag_test.go b/internal/textvarflag/flag_test.go index fd4f7997..c939ce2f 100644 --- a/internal/textvarflag/flag_test.go +++ b/internal/textvarflag/flag_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package textvarflag_test import ( diff --git a/internal/workerpool/workerpool.go b/internal/workerpool/workerpool.go index 1ca19e22..eb7eb6e5 100644 --- a/internal/workerpool/workerpool.go +++ b/internal/workerpool/workerpool.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package workerpool import ( diff --git a/internal/workerpool/workerpool_test.go b/internal/workerpool/workerpool_test.go index 2b5667f2..c0778833 100644 --- a/internal/workerpool/workerpool_test.go +++ b/internal/workerpool/workerpool_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + package workerpool_test import ( From 68337afa93b4f3c1a9c1b141b0f67ed9cef99aed Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 26 Aug 2022 07:29:18 +1000 Subject: [PATCH 086/172] Add a Makefile for making it easy to run common tasks. (#173) --- Makefile | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 Makefile diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9419b638 --- /dev/null +++ b/Makefile @@ -0,0 +1,36 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. +IMAGE_NAME = criticality-score + +default: help + + +.PHONY: help +help: ## Display this help + @awk 'BEGIN {FS = ":.*##"; \ + printf "\nUsage:\n make \033[36m\033[0m\n"} /^[a-zA-Z_0-9\/-]+:.*?##/ \ + { printf " \033[36m%-25s\033[0m %s\n", $$1, $$2 } \ + /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) + + +.PHONY: test +test: ## Run all tests + go test -race -covermode=atomic -coverprofile=unit-coverage.out './...' + + +docker-targets = build/docker/enumerate-github +.PHONY: build/docker $(docker-targets) +build/docker: $(docker-targets) ## Build all docker targets +build/docker/enumerate-github: + DOCKER_BUILDKIT=1 docker build . -f cmd/enumerate_github/Dockerfile --tag $(IMAGE_NAME)-enumerate-github From c9e07aad58f8c02be11fe39bd7e5e46863e11b59 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 26 Aug 2022 07:46:59 +1000 Subject: [PATCH 087/172] Fix a race condition in a unit test. (#174) --- internal/workerpool/workerpool_test.go | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/internal/workerpool/workerpool_test.go b/internal/workerpool/workerpool_test.go index c0778833..6cadfc85 100644 --- a/internal/workerpool/workerpool_test.go +++ b/internal/workerpool/workerpool_test.go @@ -59,6 +59,7 @@ func TestUniqueWorkerId(t *testing.T) { func TestExampleWorkload(t *testing.T) { nums := make(chan int) doubles := make(chan int) + done := make(chan bool) var results []int // Consume the doubles channel @@ -66,6 +67,7 @@ func TestExampleWorkload(t *testing.T) { for i := range doubles { results = append(results, i) } + done <- true }() // Start a pool of workers @@ -86,6 +88,12 @@ func TestExampleWorkload(t *testing.T) { // Wait for all the workers to be finished wait() + // Close the doubles channels to terminate the consumer. + close(doubles) + + // Wait for the consumer to be finished. + <-done + // Make sure all were generated if l := len(results); l != 10 { t.Fatalf("len(results) = %d; want 10", l) From ff32c5ac31a2d0b3b42673ab54d2107c82700fd4 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 30 Aug 2022 11:54:50 +1000 Subject: [PATCH 088/172] Add a docker-compose for running test infrastructure (#176) * Add a docker-compose for running test infrastructure * Add newline --- infra/test/README.md | 50 ++++++++++++++++++++++++++++++ infra/test/docker-compose.yml | 58 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 infra/test/README.md create mode 100644 infra/test/docker-compose.yml diff --git a/infra/test/README.md b/infra/test/README.md new file mode 100644 index 00000000..199c759e --- /dev/null +++ b/infra/test/README.md @@ -0,0 +1,50 @@ +# Test infrastructure using docker-compose + +This infrastructure is used during development, for local execution, or to +verify the various components work together in a cloud environment. + +## Requirements + +- Docker and Docker Compose are installed + ([docs](https://docs.docker.com/compose/install/)) +- Docker images have been built. To build them, run: + +```shell +$ make build/docker +``` + +- Environment variable `GITHUB_TOKEN` set with a GitHub personal access token. + +## Usage + +To start in daemon mode, run: + +```shell +$ docker-compose up -d +``` + +To stop, run: + +```shell +$ docker-compose down +``` + +To view logs, run: + +```shell +$ docker-compose logs -f +``` + +To restart enumerating github, run: + +``` +$ docker-compose start enumerate-github +``` + +To access the storage bucket, visit http://localhost:9000/ in a browser, with +username `minio` and password `minio123`. + +## Notes + +By default it only enumerates GitHub repositories with 100 or more stars, but +this can be set using the `CRITICALITY_SCORE_STARS_MIN` environment variable. diff --git a/infra/test/docker-compose.yml b/infra/test/docker-compose.yml new file mode 100644 index 00000000..5d2a9601 --- /dev/null +++ b/infra/test/docker-compose.yml @@ -0,0 +1,58 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +# Development configuration of Criticality Score infrastructure. +version: "3.9" +services: + minio: + image: minio/minio@sha256:684ce208c005fe032659ec77bafa6a17a16c41686c334618dec924b3505e7090 + hostname: minio + ports: + - 9000:9000 + environment: + MINIO_ROOT_USER: minio + MINIO_ROOT_PASSWORD: minio123 + MINIO_REGION_NAME: dummy_region + entrypoint: sh + command: -c 'mkdir -p /data/criticality_score && /usr/bin/minio server /data' + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 30s + timeout: 20s + retries: 3 + + auth: + image: gcr.io/openssf/scorecard-github-server:latest + hostname: auth + environment: + GITHUB_AUTH_TOKEN: "${GITHUB_TOKEN:?required}" + ports: + - 8080:8080 + + enumerate-github: + image: criticality-score-enumerate-github:latest + command: s3://criticality_score/enumeration/[[runid]]/github.txt?endpoint=minio:9000&disableSSL=true&s3ForcePathStyle=true + environment: + CRITICALITY_SCORE_OUTFILE_FORCE: 1 + CRITICALITY_SCORE_STARS_MIN: ${CRITICALITY_SCORE_STARS_MIN:-100} + CRITICALITY_SCORE_START_DATE: ${CRITICALITY_SCORE_START_DATE} + CRITICALITY_SCORE_END_DATE: ${CRITICALITY_SCORE_END_DATE} + GITHUB_AUTH_SERVER: auth:8080 + AWS_ACCESS_KEY_ID: minio + AWS_SECRET_ACCESS_KEY: minio123 + AWS_REGION: dummy_region + restart: on-failure + depends_on: + - minio + - auth From aa89935eb3c712e078df14afddf61346a14d6eeb Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 30 Aug 2022 13:28:34 +1000 Subject: [PATCH 089/172] Add golangci-lint support and fix most lint issues. (#177) - Adds support for golangci-lint via make lint - Fixes all current lint warnings --- .golangci.yml | 140 +++ Makefile | 13 +- cmd/collect_signals/depsdev/bq.go | 9 +- cmd/collect_signals/depsdev/collector.go | 9 +- cmd/collect_signals/depsdev/dependents.go | 5 +- cmd/collect_signals/github/collector.go | 33 +- cmd/collect_signals/github/factory.go | 3 +- .../github/legacy/constants.go | 4 +- .../github/legacy/contributors.go | 5 +- cmd/collect_signals/github/legacy/created.go | 1 + cmd/collect_signals/github/legacy/issues.go | 3 +- cmd/collect_signals/github/legacy/releases.go | 17 +- cmd/collect_signals/github/queries.go | 38 +- cmd/collect_signals/github/repo.go | 5 +- .../githubmentions/collector.go | 1 + cmd/collect_signals/main.go | 7 +- cmd/collect_signals/result/csv.go | 34 +- cmd/collect_signals/result/emitter.go | 6 +- cmd/collect_signals/signal/repo.go | 1 + cmd/enumerate_github/Dockerfile | 2 +- cmd/enumerate_github/githubsearch/repos.go | 43 +- cmd/enumerate_github/githubsearch/search.go | 9 +- cmd/enumerate_github/main.go | 13 +- cmd/scorer/algorithm/distribution.go | 2 +- cmd/scorer/algorithm/input.go | 5 +- cmd/scorer/config.go | 14 +- cmd/scorer/main.go | 5 +- cmd/scorer/pq.go | 10 +- go.work | 6 + go.work.sum | 19 + internal/envflag/envflag.go | 5 +- internal/githubapi/errors.go | 9 +- internal/githubapi/roundtripper.go | 26 +- internal/githubapi/roundtripper_test.go | 43 +- internal/outfile/outfile.go | 35 +- internal/outfile/outfile_test.go | 6 +- internal/retry/request.go | 8 +- internal/retry/request_test.go | 19 +- internal/textvarflag/flag_test.go | 3 +- tools/go.mod | 173 ++++ tools/go.sum | 943 ++++++++++++++++++ tools/tools.go | 20 + 42 files changed, 1544 insertions(+), 208 deletions(-) create mode 100644 .golangci.yml create mode 100644 go.work create mode 100644 go.work.sum create mode 100644 tools/go.mod create mode 100644 tools/go.sum create mode 100644 tools/tools.go diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..8761fd30 --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,140 @@ +--- +run: + concurrency: 6 + deadline: 5m +issues: + # Maximum issues count per one linter. + # Set to 0 to disable. + # Default: 50 + max-issues-per-linter: 0 + # Maximum count of issues with the same text. + # Set to 0 to disable. + # Default: 3 + max-same-issues: 0 + new-from-rev: "" +linters: + disable-all: true + enable: + - asciicheck + #- bodyclose # Temporarily disabled. + - deadcode + - depguard + - dogsled + #- errcheck # Temporarily disabled. + - errorlint + - exhaustive + - exportloopref + - gci + #- gochecknoinits # Temporarily disabled. + - gocognit + - goconst + - gocritic + - gocyclo + - godot + - godox + #- goerr113 # Temporarily disabled. + - gofmt + - gofumpt + - goheader + - goimports + - gomodguard + - goprintffuncname + - gosec + - gosimple + - govet + - ineffassign + #- lll # Temporarily disabled. + - makezero + - misspell + - nakedret + - nestif + - noctx + - nolintlint + - predeclared + - staticcheck + - stylecheck + - thelper + - tparallel + - typecheck + - unconvert + - unparam + - unused + - varcheck + - whitespace + #- wrapcheck +linters-settings: + errcheck: + check-type-assertions: true + check-blank: true + exhaustive: + # https://golangci-lint.run/usage/linters/#exhaustive + default-signifies-exhaustive: true + godot: + exclude: + - "^ -- " + govet: + enable: + - fieldalignment + godox: + keywords: + - BUG + - FIXME + - HACK + gci: + sections: + - standard + - default + - prefix(github.com/ossf/criticality_score) + gocritic: + enabled-checks: + # Diagnostic + - appendAssign + - badCond + - caseOrder + - codegenComment + - commentedOutCode + - deprecatedComment + - dupBranchBody + - dupCase + - dupSubExpr + #- exitAfterDefer # Temporarily disabled + - flagName + - nilValReturn + - weakCond + - octalLiteral + + # Performance + - appendCombine + #- hugeParam # Crashing. + - rangeExprCopy + - rangeValCopy + + # Style + - boolExprSimplify + - captLocal + - commentFormatting + - commentedOutImport + - defaultCaseOrder + - docStub + - elseif + - emptyFallthrough + - hexLiteral + - ifElseChain + - methodExprCall + - singleCaseSwitch + - typeAssertChain + - typeSwitchVar + - underef + - unlabelStmt + - unlambda + + # Opinionated + - builtinShadow + - importShadow + - initClause + - nestingReduce + - paramTypeCombine + - ptrToRefParam + - typeUnparen + - unnecessaryBlock + diff --git a/Makefile b/Makefile index 9419b638..ee511aaf 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,10 @@ # See the License for the specific language governing permissions and # limitations under the License. IMAGE_NAME = criticality-score +GOLANGCI_LINT := golangci-lint default: help - .PHONY: help help: ## Display this help @awk 'BEGIN {FS = ":.*##"; \ @@ -23,14 +23,23 @@ help: ## Display this help { printf " \033[36m%-25s\033[0m %s\n", $$1, $$2 } \ /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) - .PHONY: test test: ## Run all tests go test -race -covermode=atomic -coverprofile=unit-coverage.out './...' +.PHONY: lint +$(GOLANGCI_LINT): install/deps +lint: ## Run linter +lint: $(GOLANGCI_LINT) + $(GOLANGCI_LINT) run -c .golangci.yml docker-targets = build/docker/enumerate-github .PHONY: build/docker $(docker-targets) build/docker: $(docker-targets) ## Build all docker targets build/docker/enumerate-github: DOCKER_BUILDKIT=1 docker build . -f cmd/enumerate_github/Dockerfile --tag $(IMAGE_NAME)-enumerate-github + +.PHONY: install/deps +install/deps: ## Installs all dependencies during development and building + @echo Installing tools from tools/tools.go + @cd tools; cat tools.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go install % diff --git a/cmd/collect_signals/depsdev/bq.go b/cmd/collect_signals/depsdev/bq.go index b955bb12..ca8c2ac0 100644 --- a/cmd/collect_signals/depsdev/bq.go +++ b/cmd/collect_signals/depsdev/bq.go @@ -23,7 +23,7 @@ import ( "google.golang.org/api/iterator" ) -var NoResultError = errors.New("no results returned") +var ErrorNoResults = errors.New("no results returned") type Dataset struct { ds *bigquery.Dataset @@ -61,8 +61,8 @@ func (b *bq) OneResultQuery(ctx context.Context, query string, params map[string return err } err = it.Next(result) - if err == iterator.Done { - return NoResultError + if errors.Is(err, iterator.Done) { + return ErrorNoResults } if err != nil { return err @@ -129,6 +129,7 @@ func isNotFound(err error) bool { if err == nil { return false } - apiErr, ok := err.(*googleapi.Error) + var apiErr *googleapi.Error + ok := errors.As(err, &apiErr) return ok && apiErr.Code == 404 } diff --git a/cmd/collect_signals/depsdev/collector.go b/cmd/collect_signals/depsdev/collector.go index 0f3339b9..59a03213 100644 --- a/cmd/collect_signals/depsdev/collector.go +++ b/cmd/collect_signals/depsdev/collector.go @@ -20,14 +20,17 @@ import ( "strings" "cloud.google.com/go/bigquery" + log "github.com/sirupsen/logrus" + "github.com/ossf/criticality_score/cmd/collect_signals/collector" "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/cmd/collect_signals/signal" - log "github.com/sirupsen/logrus" ) -const defaultLocation = "US" -const DefaultDatasetName = "depsdev_analysis" +const ( + defaultLocation = "US" + DefaultDatasetName = "depsdev_analysis" +) type depsDevSet struct { DependentCount signal.Field[int] `signal:"dependent_count"` diff --git a/cmd/collect_signals/depsdev/dependents.go b/cmd/collect_signals/depsdev/dependents.go index 34ae6281..3ea95534 100644 --- a/cmd/collect_signals/depsdev/dependents.go +++ b/cmd/collect_signals/depsdev/dependents.go @@ -27,8 +27,7 @@ import ( ) const ( - dependentCountsTableName = "dependent_counts" - packageVersionToProjectTableName = "package_version_to_project" + dependentCountsTableName = "dependent_counts" snapshotQuery = "SELECT MAX(Time) AS SnapshotTime FROM `bigquery-public-data.deps_dev_v1.Snapshots`" ) @@ -143,7 +142,7 @@ func (c *dependents) Count(ctx context.Context, projectName, projectType string) if err == nil { return rec.DependentCount, true, nil } - if errors.Is(err, NoResultError) { + if errors.Is(err, ErrorNoResults) { return 0, false, nil } return 0, false, err diff --git a/cmd/collect_signals/github/collector.go b/cmd/collect_signals/github/collector.go index 4b821f36..230e5341 100644 --- a/cmd/collect_signals/github/collector.go +++ b/cmd/collect_signals/github/collector.go @@ -24,8 +24,7 @@ import ( "github.com/ossf/criticality_score/cmd/collect_signals/signal" ) -type RepoCollector struct { -} +type RepoCollector struct{} func (rc *RepoCollector) EmptySet() signal.Set { return &signal.RepoSet{} @@ -63,19 +62,19 @@ func (rc *RepoCollector) Collect(ctx context.Context, r projectrepo.Repo) (signa s.OrgCount.Set(orgCount) } ghr.logger.Debug("Fetching releases") - if releaseCount, err := legacy.FetchReleaseCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacyReleaseLookback); err != nil { + releaseCount, err := legacy.FetchReleaseCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacyReleaseLookback) + if err != nil { return nil, err + } + if releaseCount != 0 { + s.RecentReleaseCount.Set(releaseCount) } else { - if releaseCount != 0 { - s.RecentReleaseCount.Set(releaseCount) + daysSinceCreated := int(now.Sub(ghr.createdAt()).Hours()) / 24 + if daysSinceCreated > 0 { + t := (ghr.BasicData.Tags.TotalCount * legacyReleaseLookbackDays) / daysSinceCreated + s.RecentReleaseCount.Set(t) } else { - daysSinceCreated := int(now.Sub(ghr.createdAt()).Hours()) / 24 - if daysSinceCreated > 0 { - t := (ghr.BasicData.Tags.TotalCount * legacyReleaseLookbackDays) / daysSinceCreated - s.RecentReleaseCount.Set(t) - } else { - s.RecentReleaseCount.Set(0) - } + s.RecentReleaseCount.Set(0) } } return s, nil @@ -86,8 +85,7 @@ func (rc *RepoCollector) IsSupported(p projectrepo.Repo) bool { return ok } -type IssuesCollector struct { -} +type IssuesCollector struct{} func (ic *IssuesCollector) EmptySet() signal.Set { return &signal.IssuesSet{} @@ -125,12 +123,13 @@ func (ic *IssuesCollector) Collect(ctx context.Context, r projectrepo.Repo) (sig ghr.logger.Debug("Fetching comment frequency") comments, err := legacy.FetchIssueCommentCount(ctx, ghr.client, ghr.owner(), ghr.name(), legacy.IssueLookback) - if errors.Is(err, legacy.TooManyResultsError) { + switch { + case errors.Is(err, legacy.ErrorTooManyResults): ghr.logger.Debug("Comment count failed with too many result") s.CommentFrequency.Set(legacy.TooManyCommentsFrequency) - } else if err != nil { + case err != nil: return nil, err - } else { + default: s.CommentFrequency.Set(legacy.Round(float64(comments)/float64(up), 2)) } return s, nil diff --git a/cmd/collect_signals/github/factory.go b/cmd/collect_signals/github/factory.go index 194fba92..2f39187d 100644 --- a/cmd/collect_signals/github/factory.go +++ b/cmd/collect_signals/github/factory.go @@ -18,9 +18,10 @@ import ( "context" "net/url" + log "github.com/sirupsen/logrus" + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/internal/githubapi" - log "github.com/sirupsen/logrus" ) type factory struct { diff --git a/cmd/collect_signals/github/legacy/constants.go b/cmd/collect_signals/github/legacy/constants.go index c1ac8900..f40c4c07 100644 --- a/cmd/collect_signals/github/legacy/constants.go +++ b/cmd/collect_signals/github/legacy/constants.go @@ -34,6 +34,4 @@ const ( releasesPerPage = 100 ) -var ( - TooManyResultsError = errors.New("too many results") -) +var ErrorTooManyResults = errors.New("too many results") diff --git a/cmd/collect_signals/github/legacy/contributors.go b/cmd/collect_signals/github/legacy/contributors.go index 9d24b4af..2c634740 100644 --- a/cmd/collect_signals/github/legacy/contributors.go +++ b/cmd/collect_signals/github/legacy/contributors.go @@ -16,10 +16,12 @@ package legacy import ( "context" + "errors" "fmt" "strings" "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/internal/githubapi" ) @@ -114,7 +116,8 @@ func errorTooManyContributors(err error) bool { if err == nil { return false } - e, ok := err.(*github.ErrorResponse) + var e *github.ErrorResponse + ok := errors.As(err, &e) if !ok { return false } diff --git a/cmd/collect_signals/github/legacy/created.go b/cmd/collect_signals/github/legacy/created.go index 5bb712ad..b2043854 100644 --- a/cmd/collect_signals/github/legacy/created.go +++ b/cmd/collect_signals/github/legacy/created.go @@ -20,6 +20,7 @@ import ( "time" "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/internal/githubapi" ) diff --git a/cmd/collect_signals/github/legacy/issues.go b/cmd/collect_signals/github/legacy/issues.go index a9c03dde..8dc1612c 100644 --- a/cmd/collect_signals/github/legacy/issues.go +++ b/cmd/collect_signals/github/legacy/issues.go @@ -19,6 +19,7 @@ import ( "time" "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/internal/githubapi" ) @@ -68,7 +69,7 @@ func FetchIssueCommentCount(ctx context.Context, c *githubapi.Client, owner, nam cs, resp, err := c.Rest().Issues.ListComments(ctx, owner, name, 0, opts) // The API returns 5xx responses if there are too many comments. if c := githubapi.ErrorResponseStatusCode(err); 500 <= c && c < 600 { - return 0, TooManyResultsError + return 0, ErrorTooManyResults } if err != nil { return 0, err diff --git a/cmd/collect_signals/github/legacy/releases.go b/cmd/collect_signals/github/legacy/releases.go index faedc5ec..0c35dd2e 100644 --- a/cmd/collect_signals/github/legacy/releases.go +++ b/cmd/collect_signals/github/legacy/releases.go @@ -20,16 +20,16 @@ import ( "io" "time" + "github.com/shurcooL/githubv4" + "github.com/ossf/criticality_score/internal/githubapi" "github.com/ossf/criticality_score/internal/githubapi/pagination" - "github.com/shurcooL/githubv4" ) type repoReleasesQuery struct { Repository struct { Releases struct { - TotalCount int - Nodes []struct { + Nodes []struct { Release struct { CreatedAt time.Time } `graphql:"... on Release"` @@ -38,31 +38,32 @@ type repoReleasesQuery struct { EndCursor string HasNextPage bool } + TotalCount int } `graphql:"releases(orderBy:{direction:DESC, field:CREATED_AT}, first: $perPage, after: $endCursor)"` } `graphql:"repository(owner: $repositoryOwner, name: $repositoryName)"` } -// Total implements the pagination.PagedQuery interface +// Total implements the pagination.PagedQuery interface. func (r *repoReleasesQuery) Total() int { return r.Repository.Releases.TotalCount } -// Length implements the pagination.PagedQuery interface +// Length implements the pagination.PagedQuery interface. func (r *repoReleasesQuery) Length() int { return len(r.Repository.Releases.Nodes) } -// Get implements the pagination.PagedQuery interface +// Get implements the pagination.PagedQuery interface. func (r *repoReleasesQuery) Get(i int) any { return r.Repository.Releases.Nodes[i].Release.CreatedAt } -// HasNextPage implements the pagination.PagedQuery interface +// HasNextPage implements the pagination.PagedQuery interface. func (r *repoReleasesQuery) HasNextPage() bool { return r.Repository.Releases.PageInfo.HasNextPage } -// NextPageVars implements the pagination.PagedQuery interface +// NextPageVars implements the pagination.PagedQuery interface. func (r *repoReleasesQuery) NextPageVars() map[string]any { if r.Repository.Releases.PageInfo.EndCursor == "" { return map[string]any{ diff --git a/cmd/collect_signals/github/queries.go b/cmd/collect_signals/github/queries.go index 2c0604bf..75eba489 100644 --- a/cmd/collect_signals/github/queries.go +++ b/cmd/collect_signals/github/queries.go @@ -25,30 +25,21 @@ import ( const ( legacyReleaseLookbackDays = 365 - legacyReleaseLookback = time.Duration(legacyReleaseLookbackDays * 24 * time.Hour) - legacyCommitLookback = time.Duration(365 * 24 * time.Hour) + legacyReleaseLookback = legacyReleaseLookbackDays * 24 * time.Hour + legacyCommitLookback = 365 * 24 * time.Hour ) type basicRepoData struct { - Name string + Name string + URL string + MirrorURL string + Owner struct{ Login string } LicenseInfo struct{ Name string } - StargazerCount int - URL string - MirrorURL string - CreatedAt time.Time - UpdatedAt time.Time - PrimaryLanguage struct { - Name string - } - Watchers struct { - TotalCount int - } - HasIssuesEnabled bool - IsArchived bool - IsDisabled bool - IsEmpty bool - IsMirror bool + PrimaryLanguage struct{ Name string } + + CreatedAt time.Time + UpdatedAt time.Time DefaultBranchRef struct { Target struct { @@ -61,6 +52,15 @@ type basicRepoData struct { } } + StargazerCount int + HasIssuesEnabled bool + IsArchived bool + IsDisabled bool + IsEmpty bool + IsMirror bool + + Watchers struct{ TotalCount int } + Tags struct { TotalCount int } `graphql:"refs(refPrefix:\"refs/tags/\")"` diff --git a/cmd/collect_signals/github/repo.go b/cmd/collect_signals/github/repo.go index 2a3aa40e..4464ecb3 100644 --- a/cmd/collect_signals/github/repo.go +++ b/cmd/collect_signals/github/repo.go @@ -19,9 +19,10 @@ import ( "net/url" "time" + log "github.com/sirupsen/logrus" + "github.com/ossf/criticality_score/cmd/collect_signals/github/legacy" "github.com/ossf/criticality_score/internal/githubapi" - log "github.com/sirupsen/logrus" ) // repo implements the projectrepo.Repo interface for a GitHub repository. @@ -35,7 +36,7 @@ type repo struct { created time.Time } -// URL implements the projectrepo.Repo interface +// URL implements the projectrepo.Repo interface. func (r *repo) URL() *url.URL { return r.realURL } diff --git a/cmd/collect_signals/githubmentions/collector.go b/cmd/collect_signals/githubmentions/collector.go index 6df82dfe..ef955489 100644 --- a/cmd/collect_signals/githubmentions/collector.go +++ b/cmd/collect_signals/githubmentions/collector.go @@ -27,6 +27,7 @@ import ( "strings" "github.com/google/go-github/v44/github" + "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/cmd/collect_signals/signal" "github.com/ossf/criticality_score/internal/githubapi" diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 4e23ad13..1dd0b196 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -26,6 +26,10 @@ import ( "path" "strings" + "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" + sclog "github.com/ossf/scorecard/v4/log" + log "github.com/sirupsen/logrus" + "github.com/ossf/criticality_score/cmd/collect_signals/collector" "github.com/ossf/criticality_score/cmd/collect_signals/depsdev" "github.com/ossf/criticality_score/cmd/collect_signals/github" @@ -36,9 +40,6 @@ import ( "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" - "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" - sclog "github.com/ossf/scorecard/v4/log" - log "github.com/sirupsen/logrus" ) const defaultLogLevel = log.InfoLevel diff --git a/cmd/collect_signals/result/csv.go b/cmd/collect_signals/result/csv.go index 221bf30e..85faed30 100644 --- a/cmd/collect_signals/result/csv.go +++ b/cmd/collect_signals/result/csv.go @@ -25,8 +25,8 @@ import ( ) type csvWriter struct { - header []string w *csv.Writer + header []string headerWritten bool // Prevents concurrent writes to w, and headerWritten. @@ -58,40 +58,40 @@ func (w *csvWriter) Record() RecordWriter { } } -func (s *csvWriter) maybeWriteHeader() error { +func (w *csvWriter) maybeWriteHeader() error { // Check headerWritten without the lock to avoid holding the lock if the // header has already been written. - if s.headerWritten { + if w.headerWritten { return nil } // Grab the lock and re-check headerWritten just in case another goroutine // entered the same critical section. Also prevent concurrent writes to w. - s.mu.Lock() - defer s.mu.Unlock() - if s.headerWritten { + w.mu.Lock() + defer w.mu.Unlock() + if w.headerWritten { return nil } - s.headerWritten = true - return s.w.Write(s.header) + w.headerWritten = true + return w.w.Write(w.header) } -func (s *csvWriter) writeRecord(c *csvRecord) error { - if err := s.maybeWriteHeader(); err != nil { +func (w *csvWriter) writeRecord(c *csvRecord) error { + if err := w.maybeWriteHeader(); err != nil { return err } var rec []string - for _, k := range s.header { + for _, k := range w.header { rec = append(rec, c.values[k]) } // Grab the lock when we're ready to write the record to prevent // concurrent writes to w. - s.mu.Lock() - defer s.mu.Unlock() - if err := s.w.Write(rec); err != nil { + w.mu.Lock() + defer w.mu.Unlock() + if err := w.w.Write(rec); err != nil { return err } - s.w.Flush() - return s.w.Error() + w.w.Flush() + return w.w.Error() } type csvRecord struct { @@ -124,6 +124,6 @@ func marshalValue(value any) (string, error) { case nil: return "", nil default: - return "", fmt.Errorf("%w: %T", MarshalError, value) + return "", fmt.Errorf("%w: %T", ErrorMarshalFailure, value) } } diff --git a/cmd/collect_signals/result/emitter.go b/cmd/collect_signals/result/emitter.go index bc33eebd..ccec56ce 100644 --- a/cmd/collect_signals/result/emitter.go +++ b/cmd/collect_signals/result/emitter.go @@ -20,9 +20,7 @@ import ( "github.com/ossf/criticality_score/cmd/collect_signals/signal" ) -var ( - MarshalError = errors.New("failed to marshal value") -) +var ErrorMarshalFailure = errors.New("failed to marshal value") type RecordWriter interface { // WriteSignalSet is used to output the value for a signal.Set for a record. @@ -34,8 +32,6 @@ type RecordWriter interface { } type Writer interface { - //WriteAll([]signal.Set) error - // Record returns a RecordWriter that can be used to write a new record. Record() RecordWriter } diff --git a/cmd/collect_signals/signal/repo.go b/cmd/collect_signals/signal/repo.go index a23833f9..898ad25d 100644 --- a/cmd/collect_signals/signal/repo.go +++ b/cmd/collect_signals/signal/repo.go @@ -16,6 +16,7 @@ package signal import "time" +//nolint:govet type RepoSet struct { URL Field[string] Language Field[string] diff --git a/cmd/enumerate_github/Dockerfile b/cmd/enumerate_github/Dockerfile index 3056645c..0bbeda4f 100644 --- a/cmd/enumerate_github/Dockerfile +++ b/cmd/enumerate_github/Dockerfile @@ -15,7 +15,7 @@ FROM golang@sha256:684d791f8fd1b28485ee32239d92cde7099d97c88c5ed2e955f65f4adcf35d0f AS base WORKDIR /src ENV CGO_ENABLED=0 -COPY go.* ./ +COPY go.mod go.sum ./ RUN go mod download COPY . ./ diff --git a/cmd/enumerate_github/githubsearch/repos.go b/cmd/enumerate_github/githubsearch/repos.go index bd25a817..045840e1 100644 --- a/cmd/enumerate_github/githubsearch/repos.go +++ b/cmd/enumerate_github/githubsearch/repos.go @@ -19,53 +19,54 @@ import ( "fmt" "io" - "github.com/ossf/criticality_score/internal/githubapi/pagination" "github.com/shurcooL/githubv4" log "github.com/sirupsen/logrus" + + "github.com/ossf/criticality_score/internal/githubapi/pagination" ) // repo is part of the GitHub GraphQL query and includes the fields // that will be populated in a response. type repo struct { + URL string StargazerCount int - Url string } -// repoQuery is a GraphQL query for iterating over repositories in GitHub +// repoQuery is a GraphQL query for iterating over repositories in GitHub. type repoQuery struct { Search struct { - RepositoryCount int - Nodes []struct { + Nodes []struct { Repository repo `graphql:"...on Repository"` } PageInfo struct { - HasNextPage bool EndCursor string + HasNextPage bool } + RepositoryCount int } `graphql:"search(type: REPOSITORY, query: $query, first: $perPage, after: $endCursor)"` } -// Total implements the pagination.PagedQuery interface +// Total implements the pagination.PagedQuery interface. func (q *repoQuery) Total() int { return q.Search.RepositoryCount } -// Length implements the pagination.PagedQuery interface +// Length implements the pagination.PagedQuery interface. func (q *repoQuery) Length() int { return len(q.Search.Nodes) } -// Get implements the pagination.PagedQuery interface +// Get implements the pagination.PagedQuery interface. func (q *repoQuery) Get(i int) any { return q.Search.Nodes[i].Repository } -// HasNextPage implements the pagination.PagedQuery interface +// HasNextPage implements the pagination.PagedQuery interface. func (q *repoQuery) HasNextPage() bool { return q.Search.PageInfo.HasNextPage } -// NextPageVars implements the pagination.PagedQuery interface +// NextPageVars implements the pagination.PagedQuery interface. func (q *repoQuery) NextPageVars() map[string]any { if q.Search.PageInfo.EndCursor == "" { return map[string]any{ @@ -112,10 +113,11 @@ func (re *Searcher) runRepoQuery(q string) (*pagination.Cursor, error) { // // The algorithm fails if the last star value plus overlap has the same or larger value as the // previous iteration. -func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, emitter func(string)) error { +func (re *Searcher) ReposByStars(baseQuery string, minStars, overlap int, emitter func(string)) error { repos := make(map[string]empty) maxStars := -1 stars := 0 + for { q := buildQuery(baseQuery, minStars, maxStars) c, err := re.runRepoQuery(q) @@ -136,9 +138,9 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, em repo := obj.(repo) seen++ stars = repo.StargazerCount - if _, ok := repos[repo.Url]; !ok { - repos[repo.Url] = empty{} - emitter(repo.Url) + if _, ok := repos[repo.URL]; !ok { + repos[repo.URL] = empty{} + emitter(repo.URL) } } remaining := total - seen @@ -151,11 +153,13 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, em "query": q, }).Debug("Finished iterating through results") newMaxStars := stars + overlap - if remaining <= 0 { - break - } else if maxStars == -1 || newMaxStars < maxStars { + switch { + case remaining <= 0: + // nothing remains, we are done. + return nil + case maxStars == -1, newMaxStars < maxStars: maxStars = newMaxStars - } else { + default: // the gap between "stars" and "maxStars" is less than "overlap", so we can't // safely step any lower without skipping stars. re.logger.WithFields(log.Fields{ @@ -168,5 +172,4 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars int, overlap int, em return ErrorUnableToListAllResult } } - return nil } diff --git a/cmd/enumerate_github/githubsearch/search.go b/cmd/enumerate_github/githubsearch/search.go index 1bd1f06c..d4d522f4 100644 --- a/cmd/enumerate_github/githubsearch/search.go +++ b/cmd/enumerate_github/githubsearch/search.go @@ -34,8 +34,13 @@ type Searcher struct { perPage int } -type Option interface{ set(*Searcher) } -type option func(*Searcher) // option implements Option. +type Option interface { + set(*Searcher) +} + +// option implements Option. +type option func(*Searcher) + func (o option) set(s *Searcher) { o(s) } // PerPage will set how many results will per requested per page for each search query. diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index d4831ca1..8a554cd0 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -25,15 +25,16 @@ import ( "strings" "time" + "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" + sclog "github.com/ossf/scorecard/v4/log" + "github.com/shurcooL/githubv4" + log "github.com/sirupsen/logrus" + "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" "github.com/ossf/criticality_score/internal/envflag" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" - "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" - sclog "github.com/ossf/scorecard/v4/log" - "github.com/shurcooL/githubv4" - log "github.com/sirupsen/logrus" ) const ( @@ -90,7 +91,7 @@ func (d *dateFlag) String() string { } func (d *dateFlag) Time() time.Time { - return (time.Time)(*d) + return time.Time(*d) } func init() { @@ -254,6 +255,6 @@ func main() { logger.WithFields(log.Fields{ "total_repos": totalRepos, - "duration": time.Now().Sub(startTime).Truncate(time.Minute).String(), + "duration": time.Since(startTime).Truncate(time.Minute).String(), }).Info("Finished enumeration") } diff --git a/cmd/scorer/algorithm/distribution.go b/cmd/scorer/algorithm/distribution.go index ccb31566..0a72faaa 100644 --- a/cmd/scorer/algorithm/distribution.go +++ b/cmd/scorer/algorithm/distribution.go @@ -19,8 +19,8 @@ import ( ) type Distribution struct { - name string normalizeFn func(float64) float64 + name string } func (d *Distribution) String() string { diff --git a/cmd/scorer/algorithm/input.go b/cmd/scorer/algorithm/input.go index a2214316..8e5ce655 100644 --- a/cmd/scorer/algorithm/input.go +++ b/cmd/scorer/algorithm/input.go @@ -43,15 +43,14 @@ func (b Bounds) Apply(v float64) float64 { func (b Bounds) Threshold() float64 { return b.Upper - b.Lower - } type Input struct { + Source Value Bounds *Bounds - Weight float64 Distribution *Distribution - Source Value Tags []string + Weight float64 } func (i *Input) Value(fields map[string]float64) (float64, bool) { diff --git a/cmd/scorer/config.go b/cmd/scorer/config.go index 0f6e7d71..fc5aa72a 100644 --- a/cmd/scorer/config.go +++ b/cmd/scorer/config.go @@ -18,10 +18,10 @@ import ( "errors" "fmt" "io" - "io/ioutil" - "github.com/ossf/criticality_score/cmd/scorer/algorithm" "gopkg.in/yaml.v3" + + "github.com/ossf/criticality_score/cmd/scorer/algorithm" ) type Condition struct { @@ -30,15 +30,15 @@ type Condition struct { } type Input struct { - Field string `yaml:"field"` - Weight float64 `yaml:"weight"` Bounds *algorithm.Bounds `yaml:"bounds"` - Distribution string `yaml:"distribution"` Condition *Condition `yaml:"condition"` + Field string `yaml:"field"` + Distribution string `yaml:"distribution"` Tags []string `yaml:"tags"` + Weight float64 `yaml:"weight"` } -// Implements yaml.Unmarshaler interface +// Implements yaml.Unmarshaler interface. func (i *Input) UnmarshalYAML(value *yaml.Node) error { type RawInput Input raw := &RawInput{ @@ -114,7 +114,7 @@ type Config struct { // If the data cannot be parsed an error will be returned. func LoadConfig(r io.Reader) (*Config, error) { c := &Config{} - data, err := ioutil.ReadAll(r) + data, err := io.ReadAll(r) if err != nil { return nil, err } diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index 8a598af9..86b17d90 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -45,10 +45,11 @@ import ( "strconv" "strings" + log "github.com/sirupsen/logrus" + _ "github.com/ossf/criticality_score/cmd/scorer/algorithm/wam" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/textvarflag" - log "github.com/sirupsen/logrus" ) const defaultLogLevel = log.InfoLevel @@ -99,7 +100,7 @@ func makeOutHeader(header []string, resultColumn string) ([]string, error) { return append(header, resultColumn), nil } -func makeRecord(header []string, row []string) map[string]float64 { +func makeRecord(header, row []string) map[string]float64 { record := make(map[string]float64) for i, k := range header { raw := row[i] diff --git a/cmd/scorer/pq.go b/cmd/scorer/pq.go index a8654823..6581de86 100644 --- a/cmd/scorer/pq.go +++ b/cmd/scorer/pq.go @@ -30,23 +30,23 @@ type RowItem struct { // "container/heap" documentation. type PriorityQueue []*RowItem -// Len implements the heap.Interface interface +// Len implements the heap.Interface interface. func (pq PriorityQueue) Len() int { return len(pq) } -// Less implements the heap.Interface interface +// Less implements the heap.Interface interface. func (pq PriorityQueue) Less(i, j int) bool { // We want Pop to give us the highest, not lowest, priority so we use greater than here. return pq[i].score > pq[j].score } -// Swap implements the heap.Interface interface +// Swap implements the heap.Interface interface. func (pq PriorityQueue) Swap(i, j int) { pq[i], pq[j] = pq[j], pq[i] pq[i].index = i pq[j].index = j } -// Push implements the heap.Interface interface +// Push implements the heap.Interface interface. func (pq *PriorityQueue) Push(x any) { n := len(*pq) item := x.(*RowItem) @@ -54,7 +54,7 @@ func (pq *PriorityQueue) Push(x any) { *pq = append(*pq, item) } -// Pop implements the heap.Interface interface +// Pop implements the heap.Interface interface. func (pq *PriorityQueue) Pop() any { old := *pq n := len(old) diff --git a/go.work b/go.work new file mode 100644 index 00000000..74637646 --- /dev/null +++ b/go.work @@ -0,0 +1,6 @@ +go 1.19 + +use ( + . + ./tools +) diff --git a/go.work.sum b/go.work.sum new file mode 100644 index 00000000..523e3455 --- /dev/null +++ b/go.work.sum @@ -0,0 +1,19 @@ +github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= +github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= +go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= diff --git a/internal/envflag/envflag.go b/internal/envflag/envflag.go index 357c64b1..5f174bf1 100644 --- a/internal/envflag/envflag.go +++ b/internal/envflag/envflag.go @@ -26,6 +26,7 @@ package envflag import ( + "errors" "flag" "os" ) @@ -51,7 +52,7 @@ func ParseFlagSet(fs *flag.FlagSet, args []string, m Map) error { case flag.ContinueOnError: return err case flag.ExitOnError: - if err == flag.ErrHelp { + if errors.Is(err, flag.ErrHelp) { os.Exit(0) } os.Exit(2) @@ -65,7 +66,7 @@ func ParseFlagSet(fs *flag.FlagSet, args []string, m Map) error { func Parse(m Map) { if err := m.Assign(flag.CommandLine); err != nil { // flag.CommandLine is set for ExitOnError - if err == flag.ErrHelp { + if errors.Is(err, flag.ErrHelp) { os.Exit(0) } os.Exit(2) diff --git a/internal/githubapi/errors.go b/internal/githubapi/errors.go index c403d79a..b1cf0460 100644 --- a/internal/githubapi/errors.go +++ b/internal/githubapi/errors.go @@ -14,7 +14,11 @@ package githubapi -import "github.com/google/go-github/v44/github" +import ( + "errors" + + "github.com/google/go-github/v44/github" +) // ErrorResponseStatusCode will unwrap a github.ErrorResponse and return the // status code inside. @@ -25,7 +29,8 @@ func ErrorResponseStatusCode(err error) int { if err == nil { return 0 } - e, ok := err.(*github.ErrorResponse) + var e *github.ErrorResponse + ok := errors.As(err, &e) if !ok { return 0 } diff --git a/internal/githubapi/roundtripper.go b/internal/githubapi/roundtripper.go index 89c15483..99953445 100644 --- a/internal/githubapi/roundtripper.go +++ b/internal/githubapi/roundtripper.go @@ -17,7 +17,7 @@ package githubapi import ( "bytes" "encoding/json" - "io/ioutil" + "io" "net/http" "regexp" "strconv" @@ -25,12 +25,13 @@ import ( "time" "github.com/google/go-github/v44/github" - "github.com/ossf/criticality_score/internal/retry" log "github.com/sirupsen/logrus" + + "github.com/ossf/criticality_score/internal/retry" ) const ( - githubErrorIdSearch = "\"error_500\"" + githubErrorIDSearch = "\"error_500\"" ) var ( @@ -54,16 +55,16 @@ type strategies struct { } func respBodyContains(r *http.Response, search string) (bool, error) { - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) defer r.Body.Close() - r.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + r.Body = io.NopCloser(bytes.NewBuffer(data)) if err != nil { return false, err } return bytes.Contains(data, []byte(search)), nil } -// ServerError implements retry.RetryStrategyFn +// ServerError implements retry.RetryStrategyFn. func (s *strategies) ServerError(r *http.Response) (retry.RetryStrategy, error) { if r.StatusCode < 500 || 600 <= r.StatusCode { return retry.NoRetry, nil @@ -83,10 +84,9 @@ func (s *strategies) ServerError(r *http.Response) (retry.RetryStrategy, error) return retry.NoRetry, nil } return retry.RetryImmediate, nil - } -// ServerError400 implements retry.RetryStrategyFn +// ServerError400 implements retry.RetryStrategyFn. func (s *strategies) ServerError400(r *http.Response) (retry.RetryStrategy, error) { if r.StatusCode != http.StatusBadRequest { return retry.NoRetry, nil @@ -96,7 +96,7 @@ func (s *strategies) ServerError400(r *http.Response) (retry.RetryStrategy, erro return retry.NoRetry, nil } s.logger.Debug("It's a text/html doc") - if isError, err := respBodyContains(r, githubErrorIdSearch); isError { + if isError, err := respBodyContains(r, githubErrorIDSearch); isError { s.logger.Debug("Found target string - assuming 500.") return retry.RetryImmediate, nil } else { @@ -104,16 +104,16 @@ func (s *strategies) ServerError400(r *http.Response) (retry.RetryStrategy, erro } } -// SecondaryRateLimit implements retry.RetryStrategyFn +// SecondaryRateLimit implements retry.RetryStrategyFn. func (s *strategies) SecondaryRateLimit(r *http.Response) (retry.RetryStrategy, error) { if r.StatusCode != http.StatusForbidden { return retry.NoRetry, nil } s.logger.Warn("403: forbidden detected") errorResponse := &github.ErrorResponse{Response: r} - data, err := ioutil.ReadAll(r.Body) + data, err := io.ReadAll(r.Body) r.Body.Close() - r.Body = ioutil.NopCloser(bytes.NewBuffer(data)) + r.Body = io.NopCloser(bytes.NewBuffer(data)) if err != nil || data == nil { s.logger.WithFields( log.Fields{ @@ -141,7 +141,7 @@ func (s *strategies) SecondaryRateLimit(r *http.Response) (retry.RetryStrategy, return retry.NoRetry, nil } -// RetryAfter implements retry.RetryAfterFn +// RetryAfter implements retry.RetryAfterFn. // TODO: move to retry once we're confident it is working. func (s *strategies) RetryAfter(r *http.Response) time.Duration { if v := r.Header["Retry-After"]; len(v) > 0 { diff --git a/internal/githubapi/roundtripper_test.go b/internal/githubapi/roundtripper_test.go index 66f5f1b6..4a316742 100644 --- a/internal/githubapi/roundtripper_test.go +++ b/internal/githubapi/roundtripper_test.go @@ -18,30 +18,31 @@ import ( "bytes" "errors" "fmt" - "io/ioutil" + "io" "net/http" "net/url" "testing" "time" - "github.com/ossf/criticality_score/internal/retry" log "github.com/sirupsen/logrus" + + "github.com/ossf/criticality_score/internal/retry" ) const ( - testAbuseRateLimitDocUrl = "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" - testSecondaryRateLimitDocUrl = "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits" + testAbuseRateLimitDocURL = "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#abuse-rate-limits" + testSecondaryRateLimitDocURL = "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits" ) func newTestStrategies() *strategies { logger := log.New() - logger.Out = ioutil.Discard + logger.Out = io.Discard return &strategies{logger: logger} } type readerFn func(p []byte) (n int, err error) -// Read implements the io.Reader interface +// Read implements the io.Reader interface. func (r readerFn) Read(p []byte) (n int, err error) { return r(p) } @@ -141,7 +142,7 @@ func TestServerError400(t *testing.T) { r := &http.Response{ Header: http.Header{http.CanonicalHeaderKey("Content-Type"): {"text/html"}}, StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(bytes.NewBuffer([]byte(`This is an error`))), + Body: io.NopCloser(bytes.NewBuffer([]byte(`This is an error`))), } s, err := newTestStrategies().ServerError400(r) if err != nil { @@ -156,7 +157,7 @@ func TestServerError400_NoMatchingString(t *testing.T) { r := &http.Response{ Header: http.Header{http.CanonicalHeaderKey("Content-Type"): {"text/html"}}, StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(bytes.NewBuffer([]byte(`Web PageWeb PageThis is an error`))), + Body: io.NopCloser(bytes.NewBuffer([]byte(`This is an error`))), } s, err := newTestStrategies().ServerError400(r) if err != nil { @@ -240,8 +241,8 @@ func TestServerError400_StatusCodes(t *testing.T) { func TestSecondaryRateLimit(t *testing.T) { r := &http.Response{ StatusCode: http.StatusForbidden, - Body: ioutil.NopCloser(bytes.NewBuffer( - []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocUrl)))), + Body: io.NopCloser(bytes.NewBuffer( + []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL)))), } s, err := newTestStrategies().SecondaryRateLimit(r) if err != nil { @@ -255,8 +256,8 @@ func TestSecondaryRateLimit(t *testing.T) { func TestSecondaryRateLimit_AbuseUrl(t *testing.T) { r := &http.Response{ StatusCode: http.StatusForbidden, - Body: ioutil.NopCloser(bytes.NewBuffer( - []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testAbuseRateLimitDocUrl)))), + Body: io.NopCloser(bytes.NewBuffer( + []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testAbuseRateLimitDocURL)))), } s, err := newTestStrategies().SecondaryRateLimit(r) if err != nil { @@ -270,7 +271,7 @@ func TestSecondaryRateLimit_AbuseUrl(t *testing.T) { func TestSecondaryRateLimit_OtherUrl(t *testing.T) { r := &http.Response{ StatusCode: http.StatusForbidden, - Body: ioutil.NopCloser(bytes.NewBuffer([]byte(`{"message": "test", "documentation_url": "https://example.org/"}`))), + Body: io.NopCloser(bytes.NewBuffer([]byte(`{"message": "test", "documentation_url": "https://example.org/"}`))), } s, err := newTestStrategies().SecondaryRateLimit(r) if err != nil { @@ -285,7 +286,7 @@ func TestSecondaryRateLimit_BodyError(t *testing.T) { want := errors.New("test error") r := &http.Response{ StatusCode: http.StatusForbidden, - Body: ioutil.NopCloser(readerFn(func(b []byte) (int, error) { + Body: io.NopCloser(readerFn(func(b []byte) (int, error) { return 0, want })), } @@ -293,7 +294,7 @@ func TestSecondaryRateLimit_BodyError(t *testing.T) { if err == nil { t.Fatalf("ServerError() returned no error, want %v", want) } - if err != want { + if !errors.Is(err, want) { t.Fatalf("ServerError() errored %v, want %v", err, want) } } @@ -322,8 +323,8 @@ func TestSecondaryRateLimit_StatusCodes(t *testing.T) { t.Run(fmt.Sprintf("status %d", test.statusCode), func(t *testing.T) { r := &http.Response{ StatusCode: test.statusCode, - Body: ioutil.NopCloser(bytes.NewBuffer( - []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocUrl)))), + Body: io.NopCloser(bytes.NewBuffer( + []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL)))), } s, err := newTestStrategies().SecondaryRateLimit(r) if err != nil { diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index 2889aeb2..0780b7fe 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -47,18 +47,18 @@ func (f fileOpenerFunc) Open(filename string, flags int, perm os.FileMode) (*os. } type Opener struct { + fileOpener fileOpener + StdoutName string + forceFlag string force bool append bool - forceFlag string - fileOpener fileOpener Perm os.FileMode - StdoutName string } // CreateOpener creates an Opener and defines the sepecified flags forceFlag and appendFlag. -func CreateOpener(fs *flag.FlagSet, forceFlag string, appendFlag string, fileHelpName string) *Opener { +func CreateOpener(fs *flag.FlagSet, forceFlag, appendFlag, fileHelpName string) *Opener { o := &Opener{ - Perm: 0666, + Perm: 0o666, StdoutName: "-", fileOpener: fileOpenerFunc(os.OpenFile), forceFlag: forceFlag, @@ -77,7 +77,7 @@ func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, return nil, fmt.Errorf("blob store must use -%s flag", o.forceFlag) } - // Seperate the path from the URL as options may be present in the query + // Separate the path from the URL as options may be present in the query // string. prefix := u.Path u.Path = "" @@ -107,26 +107,27 @@ func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, // truncated. // - if neither forceFlag nor appendFlag are set an error will be // returned. -func (o *Opener) Open(ctx context.Context, filename string) (wc io.WriteCloser, err error) { +func (o *Opener) Open(ctx context.Context, filename string) (io.WriteCloser, error) { if o.StdoutName != "" && filename == o.StdoutName { - wc = os.Stdout + return os.Stdout, nil } else if u, e := url.Parse(filename); e == nil && u.IsAbs() { - wc, err = o.openBlobStore(ctx, u) - } else if o.append { - wc, err = o.openFile(filename, os.O_APPEND) - } else if o.force { - wc, err = o.openFile(filename, os.O_TRUNC) - } else { - wc, err = o.openFile(filename, os.O_EXCL) + return o.openBlobStore(ctx, u) + } + switch { + case o.append: + return o.openFile(filename, os.O_APPEND) + case o.force: + return o.openFile(filename, os.O_TRUNC) + default: + return o.openFile(filename, os.O_EXCL) } - return } var defaultOpener *Opener // DefineFlags is a wrapper around CreateOpener for updating a default instance // of Opener. -func DefineFlags(fs *flag.FlagSet, forceFlag string, appendFlag string, fileHelpName string) { +func DefineFlags(fs *flag.FlagSet, forceFlag, appendFlag, fileHelpName string) { defaultOpener = CreateOpener(fs, forceFlag, appendFlag, fileHelpName) } diff --git a/internal/outfile/outfile_test.go b/internal/outfile/outfile_test.go index e466c232..f5e7b858 100644 --- a/internal/outfile/outfile_test.go +++ b/internal/outfile/outfile_test.go @@ -39,7 +39,7 @@ func newTestOpener() *testOpener { o := &testOpener{} o.flag = flag.NewFlagSet("", flag.ContinueOnError) o.opener = CreateOpener(o.flag, "force", "append", "FILE") - o.opener.Perm = 0567 + o.opener.Perm = 0o567 o.opener.StdoutName = "-stdout-" o.opener.fileOpener = fileOpenerFunc(func(filename string, flags int, perm os.FileMode) (*os.File, error) { o.lastOpen = &openCall{ @@ -108,6 +108,7 @@ func TestOpenBucketUrlNoForceFlag(t *testing.T) { } func TestOpenFlagTest(t *testing.T) { + //nolint:govet tests := []struct { name string args []string @@ -148,7 +149,7 @@ func TestOpenFlagTest(t *testing.T) { if f == nil { t.Fatal("Open() == nil, want a file") } - assertLastOpen(t, o, "path/to/file", test.expectedFlag, 0567) + assertLastOpen(t, o, "path/to/file", test.expectedFlag, 0o567) }) } @@ -167,6 +168,7 @@ func TestOpenFlagTest(t *testing.T) { } func assertLastOpen(t *testing.T, o *testOpener, filename string, requireFlags int, perm os.FileMode) { + t.Helper() if o.lastOpen == nil { t.Fatalf("Open(...) not called, want call to Open(...)") } diff --git a/internal/retry/request.go b/internal/retry/request.go index 967c8ed5..1ed12cab 100644 --- a/internal/retry/request.go +++ b/internal/retry/request.go @@ -25,9 +25,7 @@ const ( DefaultInitialDuration = 2 * time.Minute ) -var ( - ErrorNoMoreAttempts = errors.New("request cannot by retried") -) +var ErrorNoMoreAttempts = errors.New("request cannot by retried") type RetryStrategy int @@ -84,12 +82,12 @@ func DefaultBackoff(d time.Duration) time.Duration { } type Options struct { - maxRetries int - initialDelay time.Duration backoff BackoffFn sleep sleepFn retryAfter RetryAfterFn retryStrategyFuncs []RetryStrategyFn + maxRetries int + initialDelay time.Duration } type Option interface { Apply(*Options) diff --git a/internal/retry/request_test.go b/internal/retry/request_test.go index d13009a7..d19be41d 100644 --- a/internal/retry/request_test.go +++ b/internal/retry/request_test.go @@ -15,8 +15,9 @@ package retry import ( + "errors" "fmt" - "io/ioutil" + "io" "net/http" "strings" "testing" @@ -27,7 +28,7 @@ func TestInit_NotDone(t *testing.T) { req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), }, nil }, MakeOptions()) @@ -40,7 +41,7 @@ func Test200NoRetryStrategyFunc(t *testing.T) { req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), }, nil }, MakeOptions()) resp, err := req.Do() @@ -60,7 +61,7 @@ func TestDoAfterDoneReturnsError(t *testing.T) { req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusOK, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), }, nil }, MakeOptions()) @@ -69,7 +70,7 @@ func TestDoAfterDoneReturnsError(t *testing.T) { // This Do() returns an error. resp, err := req.Do() - if err != ErrorNoMoreAttempts { + if !errors.Is(err, ErrorNoMoreAttempts) { t.Fatalf("Do() returned err %v; want %v", err, ErrorNoMoreAttempts) } if resp != nil { @@ -83,7 +84,7 @@ func Test2xx3xxAlwaysDone(t *testing.T) { req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: code, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), }, nil }, MakeOptions(Strategy(func(_ *http.Response) (RetryStrategy, error) { // Always force a retry if the strategy is called. @@ -101,7 +102,7 @@ func TestRetryAfterZeroDuration(t *testing.T) { req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), }, nil }, MakeOptions(RetryAfter(func(_ *http.Response) time.Duration { return 0 @@ -123,7 +124,7 @@ func TestRetryAfterDuration(t *testing.T) { req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), }, nil }, opts) req.Do() @@ -144,7 +145,7 @@ func TestZeroMaxRetriesOnlyTriesOnce(t *testing.T) { req := NewRequest(&http.Request{}, func(r *http.Request) (*http.Response, error) { return &http.Response{ StatusCode: http.StatusBadRequest, - Body: ioutil.NopCloser(strings.NewReader("")), + Body: io.NopCloser(strings.NewReader("")), }, nil }, MakeOptions(MaxRetries(0), RetryAfter(func(_ *http.Response) time.Duration { // Force a retry diff --git a/internal/textvarflag/flag_test.go b/internal/textvarflag/flag_test.go index c939ce2f..2f20fff9 100644 --- a/internal/textvarflag/flag_test.go +++ b/internal/textvarflag/flag_test.go @@ -19,8 +19,9 @@ import ( "net" "testing" - "github.com/ossf/criticality_score/internal/textvarflag" "github.com/sirupsen/logrus" + + "github.com/ossf/criticality_score/internal/textvarflag" ) var defaultIP = net.IPv4(192, 168, 0, 100) diff --git a/tools/go.mod b/tools/go.mod new file mode 100644 index 00000000..935fb74a --- /dev/null +++ b/tools/go.mod @@ -0,0 +1,173 @@ +module github.com/ossf/criticality_score/tools + +go 1.19 + +require ( + 4d63.com/gochecknoglobals v0.1.0 // indirect + github.com/Antonboom/errname v0.1.7 // indirect + github.com/Antonboom/nilnil v0.1.1 // indirect + github.com/BurntSushi/toml v1.2.0 // indirect + github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect + github.com/Masterminds/semver v1.5.0 // indirect + github.com/OpenPeeDeeP/depguard v1.1.0 // indirect + github.com/alexkohler/prealloc v1.0.0 // indirect + github.com/alingse/asasalint v0.0.11 // indirect + github.com/ashanbrown/forbidigo v1.3.0 // indirect + github.com/ashanbrown/makezero v1.1.1 // indirect + github.com/beorn7/perks v1.0.1 // indirect + github.com/bkielbasa/cyclop v1.2.0 // indirect + github.com/blizzy78/varnamelen v0.8.0 // indirect + github.com/bombsimon/wsl/v3 v3.3.0 // indirect + github.com/breml/bidichk v0.2.3 // indirect + github.com/breml/errchkjson v0.3.0 // indirect + github.com/butuzov/ireturn v0.1.1 // indirect + github.com/cespare/xxhash/v2 v2.1.2 // indirect + github.com/charithe/durationcheck v0.0.9 // indirect + github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect + github.com/curioswitch/go-reassign v0.1.2 // indirect + github.com/daixiang0/gci v0.6.3 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/denis-tingaikin/go-header v0.4.3 // indirect + github.com/esimonov/ifshort v1.0.4 // indirect + github.com/ettle/strcase v0.1.1 // indirect + github.com/fatih/color v1.13.0 // indirect + github.com/fatih/structtag v1.2.0 // indirect + github.com/firefart/nonamedreturns v1.0.4 // indirect + github.com/fsnotify/fsnotify v1.5.4 // indirect + github.com/fzipp/gocyclo v0.6.0 // indirect + github.com/go-critic/go-critic v0.6.4 // indirect + github.com/go-toolsmith/astcast v1.0.0 // indirect + github.com/go-toolsmith/astcopy v1.0.1 // indirect + github.com/go-toolsmith/astequal v1.0.2 // indirect + github.com/go-toolsmith/astfmt v1.0.0 // indirect + github.com/go-toolsmith/astp v1.0.0 // indirect + github.com/go-toolsmith/strparse v1.0.0 // indirect + github.com/go-toolsmith/typep v1.0.2 // indirect + github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/golang/protobuf v1.5.2 // indirect + github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect + github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect + github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect + github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect + github.com/golangci/golangci-lint v1.49.0 // indirect + github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect + github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect + github.com/golangci/misspell v0.3.5 // indirect + github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect + github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect + github.com/google/go-cmp v0.5.8 // indirect + github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gostaticanalysis/analysisutil v0.7.1 // indirect + github.com/gostaticanalysis/comment v1.4.2 // indirect + github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect + github.com/gostaticanalysis/nilerr v0.1.1 // indirect + github.com/hashicorp/errwrap v1.0.0 // indirect + github.com/hashicorp/go-multierror v1.1.1 // indirect + github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hexops/gotextdiff v1.0.3 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jgautheron/goconst v1.5.1 // indirect + github.com/jingyugao/rowserrcheck v1.1.1 // indirect + github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect + github.com/julz/importas v0.1.0 // indirect + github.com/kisielk/errcheck v1.6.2 // indirect + github.com/kisielk/gotool v1.0.0 // indirect + github.com/kulti/thelper v0.6.3 // indirect + github.com/kunwardeep/paralleltest v1.0.6 // indirect + github.com/kyoh86/exportloopref v0.1.8 // indirect + github.com/ldez/gomoddirectives v0.2.3 // indirect + github.com/ldez/tagliatelle v0.3.1 // indirect + github.com/leonklingele/grouper v1.1.0 // indirect + github.com/lufeee/execinquery v1.2.1 // indirect + github.com/magiconair/properties v1.8.6 // indirect + github.com/maratori/testpackage v1.1.0 // indirect + github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/mbilski/exhaustivestruct v1.2.0 // indirect + github.com/mgechev/revive v1.2.3 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/moricho/tparallel v0.2.1 // indirect + github.com/nakabonne/nestif v0.3.1 // indirect + github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect + github.com/nishanths/exhaustive v0.8.1 // indirect + github.com/nishanths/predeclared v0.2.2 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.0.2 // indirect + github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/polyfloyd/go-errorlint v1.0.2 // indirect + github.com/prometheus/client_golang v1.12.1 // indirect + github.com/prometheus/client_model v0.2.0 // indirect + github.com/prometheus/common v0.32.1 // indirect + github.com/prometheus/procfs v0.7.3 // indirect + github.com/quasilyte/go-ruleguard v0.3.17 // indirect + github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect + github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect + github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/ryancurrah/gomodguard v1.2.4 // indirect + github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect + github.com/sashamelentyev/interfacebloat v1.1.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.13.0 // indirect + github.com/securego/gosec/v2 v2.13.1 // indirect + github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect + github.com/sirupsen/logrus v1.9.0 // indirect + github.com/sivchari/containedctx v1.0.2 // indirect + github.com/sivchari/nosnakecase v1.7.0 // indirect + github.com/sivchari/tenv v1.7.0 // indirect + github.com/sonatard/noctx v0.0.1 // indirect + github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/spf13/afero v1.8.2 // indirect + github.com/spf13/cast v1.5.0 // indirect + github.com/spf13/cobra v1.5.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.12.0 // indirect + github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect + github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect + github.com/stretchr/objx v0.4.0 // indirect + github.com/stretchr/testify v1.8.0 // indirect + github.com/subosito/gotenv v1.4.0 // indirect + github.com/sylvia7788/contextcheck v1.0.6 // indirect + github.com/tdakkota/asciicheck v0.1.1 // indirect + github.com/tetafro/godot v1.4.11 // indirect + github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect + github.com/timonwong/logrlint v0.1.0 // indirect + github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect + github.com/ultraware/funlen v0.0.3 // indirect + github.com/ultraware/whitespace v0.0.5 // indirect + github.com/uudashr/gocognit v1.0.6 // indirect + github.com/yagipy/maintidx v1.0.0 // indirect + github.com/yeya24/promlinter v0.2.0 // indirect + gitlab.com/bosi/decorder v0.2.3 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.17.0 // indirect + golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect + golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect + golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect + golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + golang.org/x/text v0.3.7 // indirect + golang.org/x/tools v0.1.12 // indirect + google.golang.org/protobuf v1.28.0 // indirect + gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + honnef.co/go/tools v0.3.3 // indirect + mvdan.cc/gofumpt v0.3.1 // indirect + mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect + mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect + mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect +) diff --git a/tools/go.sum b/tools/go.sum new file mode 100644 index 00000000..87d8925a --- /dev/null +++ b/tools/go.sum @@ -0,0 +1,943 @@ +4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= +4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= +cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= +cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.44.3/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= +cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= +cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= +cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= +cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI= +cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= +cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= +cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= +cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= +cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= +github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= +github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= +github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= +github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7IAzX8QezqtFV9m0MUHFJgts= +github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= +github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= +github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= +github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= +github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= +github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= +github.com/ashanbrown/forbidigo v1.3.0 h1:VkYIwb/xxdireGAdJNZoo24O4lmnEWkactplBlWTShc= +github.com/ashanbrown/forbidigo v1.3.0/go.mod h1:vVW7PEdqEFqapJe95xHkTfB1+XvZXBFg8t0sG2FIxmI= +github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= +github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bkielbasa/cyclop v1.2.0 h1:7Jmnh0yL2DjKfw28p86YTd/B4lRGcNuu12sKE35sM7A= +github.com/bkielbasa/cyclop v1.2.0/go.mod h1:qOI0yy6A7dYC4Zgsa72Ppm9kONl0RoIlPbzot9mhmeI= +github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= +github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= +github.com/bombsimon/wsl/v3 v3.3.0 h1:Mka/+kRLoQJq7g2rggtgQsjuI/K5Efd87WX96EWFxjM= +github.com/bombsimon/wsl/v3 v3.3.0/go.mod h1:st10JtZYLE4D5sC7b8xV4zTKZwAQjCH/Hy2Pm1FNZIc= +github.com/breml/bidichk v0.2.3 h1:qe6ggxpTfA8E75hdjWPZ581sY3a2lnl0IRxLQFelECI= +github.com/breml/bidichk v0.2.3/go.mod h1:8u2C6DnAy0g2cEq+k/A2+tr9O1s+vHGxWn0LTc70T2A= +github.com/breml/errchkjson v0.3.0 h1:YdDqhfqMT+I1vIxPSas44P+9Z9HzJwCeAzjB8PxP1xw= +github.com/breml/errchkjson v0.3.0/go.mod h1:9Cogkyv9gcT8HREpzi3TiqBxCqDzo8awa92zSDFcofU= +github.com/butuzov/ireturn v0.1.1 h1:QvrO2QF2+/Cx1WA/vETCIYBKtRjc30vesdoPUNo1EbY= +github.com/butuzov/ireturn v0.1.1/go.mod h1:Wh6Zl3IMtTpaIKbmwzqi6olnM9ptYQxxVacMsOEFPoc= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= +github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= +github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= +github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cristalhq/acmd v0.7.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= +github.com/curioswitch/go-reassign v0.1.2 h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc/tlYpkmI= +github.com/curioswitch/go-reassign v0.1.2/go.mod h1:bFJIHgtTM3hRm2sKXSPkbwNjSFyGURQXyn4IXD2qwfQ= +github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E= +github.com/daixiang0/gci v0.6.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denis-tingaikin/go-header v0.4.3 h1:tEaZKAlqql6SKCY++utLmkPLd6K8IBM20Ha7UVm+mtU= +github.com/denis-tingaikin/go-header v0.4.3/go.mod h1:0wOCWuN71D5qIgE2nz9KrKmuYBAC2Mra5RassOIQ2/c= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStBA= +github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= +github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= +github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= +github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= +github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= +github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= +github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E= +github.com/go-critic/go-critic v0.6.4/go.mod h1:qL5SOlk7NtY6sJPoVCTKDIgzNOxHkkkOCVDyi9wJe1U= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= +github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= +github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= +github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= +github.com/go-toolsmith/astcopy v1.0.1 h1:l09oBhAPyV74kLJ3ZO31iBU8htZGTwr9LTjuMCyL8go= +github.com/go-toolsmith/astcopy v1.0.1/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= +github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= +github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= +github.com/go-toolsmith/astequal v1.0.2 h1:+XvaV8zNxua+9+Oa4AHmgmpo4RYAbwr/qjNppLfX2yM= +github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= +github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= +github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= +github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= +github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= +github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= +github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= +github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= +github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 h1:23T5iq8rbUYlhpt5DB4XJkc6BU31uODLD1o1gKvZmD0= +github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2/go.mod h1:k9Qvh+8juN+UKMCS/3jFtGICgW8O96FVaZsaxdzDkR4= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo= +github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= +github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= +github.com/golangci/golangci-lint v1.49.0 h1:I8WHOavragDttlLHtSraHn/h39C+R60bEQ5NoGcHQr8= +github.com/golangci/golangci-lint v1.49.0/go.mod h1:+V/7lLv449R6w9mQ3WdV0EKh7Je/jTylMeSwBZcLeWE= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= +github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= +github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= +github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= +github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= +github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= +github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4/go.mod h1:Izgrg8RkN3rCIMLGE9CyYmU9pY2Jer6DgANEnZ/L/cQ= +github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= +github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= +github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= +github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= +github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= +github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= +github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= +github.com/gostaticanalysis/comment v1.3.0/go.mod h1:xMicKDx7XRXYdVwY9f9wQpDJVnqWxw9wCauCMKp+IBI= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= +github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= +github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= +github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= +github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= +github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= +github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= +github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= +github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= +github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= +github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= +github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= +github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= +github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= +github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= +github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= +github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= +github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= +github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= +github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= +github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= +github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= +github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= +github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= +github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= +github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= +github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/moricho/tparallel v0.2.1 h1:95FytivzT6rYzdJLdtfn6m1bfFJylOJK41+lgv/EHf4= +github.com/moricho/tparallel v0.2.1/go.mod h1:fXEIZxG2vdfl0ZF8b42f5a78EhjjD5mX8qUplsoSU4k= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= +github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo= +github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= +github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= +github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= +github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= +github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= +github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polyfloyd/go-errorlint v1.0.2 h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk= +github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= +github.com/quasilyte/go-ruleguard v0.3.17 h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI= +github.com/quasilyte/go-ruleguard v0.3.17/go.mod h1:sST5PvaR7yb/Az5ksX8oc88usJ4EGjmJv7cK7y3jyig= +github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/dsl v0.3.21/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= +github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8= +github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= +github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= +github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= +github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= +github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= +github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= +github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= +github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= +github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= +github.com/sashamelentyev/usestdlibvars v1.13.0 h1:uObNudVEEHf6JbOJy5bgKJloA1bWjxR9fwgNFpPzKnI= +github.com/sashamelentyev/usestdlibvars v1.13.0/go.mod h1:D2Wb7niIYmTB+gB8z7kh8tyP5ccof1dQ+SFk+WW5NtY= +github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= +github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYIc1yrHI= +github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= +github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= +github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= +github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= +github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= +github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= +github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= +github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= +github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= +github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= +github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= +github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= +github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= +github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= +github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= +github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= +github.com/sylvia7788/contextcheck v1.0.6/go.mod h1:9XDxwvxyuKD+8N+a7Gs7bfWLityh5t70g/GjdEt2N2M= +github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= +github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= +github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= +github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= +github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timonwong/logrlint v0.1.0 h1:phZCcypL/vtx6cGxObJgWZ5wexZF5SXFPLOM+ru0e/M= +github.com/timonwong/logrlint v0.1.0/go.mod h1:Zleg4Gw+kRxNej+Ra7o+tEaW5k1qthTaYKU7rSD39LU= +github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M= +github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= +github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= +github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= +github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= +github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= +github.com/ultraware/whitespace v0.0.5/go.mod h1:aVMh/gQve5Maj9hQ/hg+F75lr/X5A89uZnzAmWSineA= +github.com/uudashr/gocognit v1.0.6 h1:2Cgi6MweCsdB6kpcVQp7EW4U23iBFQWfTXiWlyp842Y= +github.com/uudashr/gocognit v1.0.6/go.mod h1:nAIUuVBnYU7pcninia3BHOvQkpQCeO76Uscky5BOwcY= +github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= +github.com/yeya24/promlinter v0.2.0 h1:xFKDQ82orCU5jQujdaD8stOHiv8UN68BSdn2a8u8Y3o= +github.com/yeya24/promlinter v0.2.0/go.mod h1:u54lkmBOZrpEbQQ6gox2zWKKLKu2SGe+2KOiextY+IA= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +gitlab.com/bosi/decorder v0.2.3 h1:gX4/RgK16ijY8V+BRQHAySfQAb354T7/xQpDB2n10P0= +gitlab.com/bosi/decorder v0.2.3/go.mod h1:9K1RB5+VPNQYtXtTDAzd2OEftsZb1oV0IrJrzChSdGE= +go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= +go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= +go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.17.0 h1:MTjgFu6ZLKvY6Pvaqk97GlxNBuMpV4Hy/3P6tRGlI2U= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= +golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= +golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= +golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= +golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190307163923-6a08e3108db3/go.mod h1:25r3+/G6/xytQM8iWZKq3Hn0kr0rgFKPUNVEL/dr3z4= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190916130336-e45ffcd953cc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117220505-0cba7a3a9ee9/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200414032229-332987a829c3/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200812195022-5ae4c3c160a0/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201230224404-63754364767c/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= +google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= +google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= +google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= +google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg= +google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE= +google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= +google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= +google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= +gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= +honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= +mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8= +mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= +mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= +mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= +mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= +mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= +rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/tools/tools.go b/tools/tools.go new file mode 100644 index 00000000..043e922c --- /dev/null +++ b/tools/tools.go @@ -0,0 +1,20 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package main + +// This set of imports is used to ensure `go mod tidy` does not remove them. +import ( + _ "github.com/golangci/golangci-lint/cmd/golangci-lint" +) From 49f689b53300899dc86e090a94e8efbf337b0897 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 30 Aug 2022 14:03:31 +1000 Subject: [PATCH 090/172] Add a cloudbuild.yaml for enumerate_github repository. (#178) Signed-off-by: Caleb Brown --- .../enumerate_github/cloudbuild.yaml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 infra/cloudbuild/enumerate_github/cloudbuild.yaml diff --git a/infra/cloudbuild/enumerate_github/cloudbuild.yaml b/infra/cloudbuild/enumerate_github/cloudbuild.yaml new file mode 100644 index 00000000..1fa81a7b --- /dev/null +++ b/infra/cloudbuild/enumerate_github/cloudbuild.yaml @@ -0,0 +1,22 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +steps: +- name: 'gcr.io/cloud-builders/docker' + args: ['build', '.', + '--build-arg', 'COMMIT_SHA=$COMMIT_SHA', + '-t', 'gcr.io/openssf/criticality-score-enumerate-github:$COMMIT_SHA', + '-t', 'gcr.io/openssf/criticality-score-enumerate-github:latest', + '-f', 'cmd/enumerate_github/Dockerfile'] +images: ['gcr.io/openssf/criticality-score-enumerate-github'] From 6e285cd42346bcd8ec70f183af5a15063b2f03df Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 1 Sep 2022 09:10:00 +1000 Subject: [PATCH 091/172] Add an initial k8s config for running the enumerate_github tool. (#179) Only runs for repos >= 100 stars, for 2021. It is triggered each day at 23:00 UTC or 9am AEST. Signed-off-by: Caleb Brown --- infra/k8s/enumerate_github.yaml | 48 +++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 infra/k8s/enumerate_github.yaml diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml new file mode 100644 index 00000000..d239f4b8 --- /dev/null +++ b/infra/k8s/enumerate_github.yaml @@ -0,0 +1,48 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: criticality-score-enumerate-github +spec: + # Initially, run this daily at 23:00UTC for >=100 stars across 2021. + schedule: "0 23 * * *" + concurrencyPolicy: "Forbid" + jobTemplate: + spec: + template: + spec: + containers: + - name: enumerate-github + image: gcr.io/openssf/criticality-score-enumerate-github:latest + args: ["gcs://ossf-criticality-score-url-data/[[runid]]/github.txt"] + imagePullPolicy: Always + env: + - name: GITHUB_AUTH_SERVER + value: "10.4.4.210:80" + - name: CRITICALITY_SCORE_OUTFILE_FORCE + value: "1" + - name: CRITICALITY_SCORE_STARS_MIN + value: "100" + - name: CRITICALITY_SCORE_START_DATE + value: "2021-01-01" + - name: CRITICALITY_SCORE_END_DATE + value: "2022-01-01" + resources: + limits: + memory: 1Gi + requests: + memory: 1Gi + restartPolicy: OnFailure From 7a71116d1d93aecac089cb092ecb09a2c58810a7 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 1 Sep 2022 10:30:04 +1000 Subject: [PATCH 092/172] Fix the broken GCS link, extend the memory limits. (#180) Signed-off-by: Caleb Brown --- infra/k8s/enumerate_github.yaml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml index d239f4b8..b1d410d6 100644 --- a/infra/k8s/enumerate_github.yaml +++ b/infra/k8s/enumerate_github.yaml @@ -27,7 +27,7 @@ spec: containers: - name: enumerate-github image: gcr.io/openssf/criticality-score-enumerate-github:latest - args: ["gcs://ossf-criticality-score-url-data/[[runid]]/github.txt"] + args: ["gs://ossf-criticality-score-url-data/[[runid]]/github.txt"] imagePullPolicy: Always env: - name: GITHUB_AUTH_SERVER @@ -42,7 +42,7 @@ spec: value: "2022-01-01" resources: limits: - memory: 1Gi + memory: 5Gi requests: - memory: 1Gi + memory: 2Gi restartPolicy: OnFailure From f56aa70ce92e3fce2ee4bdc445444484406b520b Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 1 Sep 2022 11:58:04 +1000 Subject: [PATCH 093/172] Trim the "/" from the start of the bucket path. (#181) Signed-off-by: Caleb Brown --- internal/outfile/outfile.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index 0780b7fe..3256c27b 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -21,6 +21,7 @@ import ( "io" "net/url" "os" + "strings" "gocloud.dev/blob" _ "gocloud.dev/blob/fileblob" @@ -79,7 +80,7 @@ func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, // Separate the path from the URL as options may be present in the query // string. - prefix := u.Path + prefix := strings.TrimPrefix(u.Path, "/") u.Path = "" bucket := u.String() From 60c82024b2395d2259231c09ceffcf03b551c8ba Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 5 Sep 2022 11:09:53 +1000 Subject: [PATCH 094/172] Switch to Zap for logging instead of Logrus. (#182) Zap is better maintained and more useful. Logrus is in maintenence mode. zapdriver is added for GCP support. Its not well maintained, but has few dependencies, so it is okay. Signed-off-by: Caleb Brown --- cmd/enumerate_github/githubsearch/repos.go | 38 ++++---- cmd/enumerate_github/githubsearch/search.go | 6 +- cmd/enumerate_github/main.go | 102 +++++++++++--------- go.mod | 5 + go.sum | 12 +++ infra/k8s/enumerate_github.yaml | 2 + 6 files changed, 99 insertions(+), 66 deletions(-) diff --git a/cmd/enumerate_github/githubsearch/repos.go b/cmd/enumerate_github/githubsearch/repos.go index 045840e1..b548d77e 100644 --- a/cmd/enumerate_github/githubsearch/repos.go +++ b/cmd/enumerate_github/githubsearch/repos.go @@ -20,7 +20,7 @@ import ( "io" "github.com/shurcooL/githubv4" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" "github.com/ossf/criticality_score/internal/githubapi/pagination" ) @@ -89,9 +89,9 @@ func buildQuery(q string, minStars, maxStars int) string { } func (re *Searcher) runRepoQuery(q string) (*pagination.Cursor, error) { - re.logger.WithFields(log.Fields{ - "query": q, - }).Debug("Searching GitHub") + re.logger.With( + zap.String("query", q), + ).Debug("Searching GitHub") vars := map[string]any{ "query": githubv4.String(q), "perPage": githubv4.Int(re.perPage), @@ -144,14 +144,14 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars, overlap int, emitte } } remaining := total - seen - re.logger.WithFields(log.Fields{ - "total_available": total, - "total_returned": seen, - "total_remaining": remaining, - "unique_repos": len(repos), - "last_stars": stars, - "query": q, - }).Debug("Finished iterating through results") + re.logger.With( + zap.Int("total_available", total), + zap.Int("total_returned", seen), + zap.Int("total_remaining", remaining), + zap.Int("unique_repos", len(repos)), + zap.Int("last_stars", stars), + zap.String("query", q), + ).Debug("Finished iterating through results") newMaxStars := stars + overlap switch { case remaining <= 0: @@ -162,13 +162,13 @@ func (re *Searcher) ReposByStars(baseQuery string, minStars, overlap int, emitte default: // the gap between "stars" and "maxStars" is less than "overlap", so we can't // safely step any lower without skipping stars. - re.logger.WithFields(log.Fields{ - "error": ErrorUnableToListAllResult, - "min_stars": minStars, - "stars": stars, - "max_stars": maxStars, - "overlap": overlap, - }).Error("Too many repositories for current range") + re.logger.With( + zap.Error(ErrorUnableToListAllResult), + zap.Int("min_stars", minStars), + zap.Int("stars", stars), + zap.Int("max_stars", maxStars), + zap.Int("overlap", overlap), + ).Error("Too many repositories for current range") return ErrorUnableToListAllResult } } diff --git a/cmd/enumerate_github/githubsearch/search.go b/cmd/enumerate_github/githubsearch/search.go index d4d522f4..f37b652a 100644 --- a/cmd/enumerate_github/githubsearch/search.go +++ b/cmd/enumerate_github/githubsearch/search.go @@ -19,7 +19,7 @@ import ( "errors" "github.com/shurcooL/githubv4" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" ) // empty is a convenience wrapper for the empty struct. @@ -30,7 +30,7 @@ var ErrorUnableToListAllResult = errors.New("unable to list all results") type Searcher struct { ctx context.Context client *githubv4.Client - logger *log.Entry + logger *zap.Logger perPage int } @@ -48,7 +48,7 @@ func PerPage(perPage int) Option { return option(func(s *Searcher) { s.perPage = perPage }) } -func NewSearcher(ctx context.Context, client *githubv4.Client, logger *log.Entry, options ...Option) *Searcher { +func NewSearcher(ctx context.Context, client *githubv4.Client, logger *zap.Logger, options ...Option) *Searcher { s := &Searcher{ ctx: ctx, client: client, diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 8a554cd0..4c569cfe 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -25,13 +25,16 @@ import ( "strings" "time" + "github.com/go-logr/zapr" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" sclog "github.com/ossf/scorecard/v4/log" "github.com/shurcooL/githubv4" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" "github.com/ossf/criticality_score/internal/envflag" + log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" @@ -41,7 +44,7 @@ const ( githubDateFormat = "2006-01-02" reposPerPage = 100 oneDay = time.Hour * 24 - defaultLogLevel = log.InfoLevel + defaultLogLevel = zapcore.InfoLevel runIDToken = "[[runid]]" runIDDateFormat = "20060102-1504" ) @@ -57,10 +60,12 @@ var ( workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") startDateFlag = dateFlag(epochDate) endDateFlag = dateFlag(time.Now().UTC().Truncate(oneDay)) - logLevel log.Level + logLevel = defaultLogLevel + logEnv log.Env // Maps environment variables to the flags they correspond to. envFlagMap = envflag.Map{ + "CRITICALITY_SCORE_LOG_ENV": "log-env", "CRITICALITY_SCORE_LOG_LEVEL": "log", "CRITICALITY_SCORE_WORKERS": "workers", "CRITICALITY_SCORE_START_DATE": "start", @@ -97,7 +102,8 @@ func (d *dateFlag) Time() time.Time { func init() { flag.Var(&startDateFlag, "start", "the start `date` to enumerate back to. Must be at or after 2008-01-01.") flag.Var(&endDateFlag, "end", "the end `date` to enumerate from.") - textvarflag.TextVar(flag.CommandLine, &logLevel, "log", defaultLogLevel, "set the `level` of logging.") + flag.Var(&logLevel, "log", "set the `level` of logging.") + textvarflag.TextVar(flag.CommandLine, &logEnv, "log-env", log.DefaultEnv, "set logging `env`.") outfile.DefineFlags(flag.CommandLine, "force", "append", "FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -112,7 +118,7 @@ func init() { // searchWorker waits for a query on the queries channel, starts a search with that query using s // and returns each repository on the results channel. -func searchWorker(s *githubsearch.Searcher, logger *log.Entry, queries, results chan string) { +func searchWorker(s *githubsearch.Searcher, logger *zap.Logger, queries, results chan string) { for q := range queries { total := 0 err := s.ReposByStars(q, *minStarsFlag, *starOverlapFlag, func(repo string) { @@ -121,10 +127,10 @@ func searchWorker(s *githubsearch.Searcher, logger *log.Entry, queries, results }) if err != nil { // TODO: this error handling is not at all graceful, and hard to recover from. - logger.WithFields(log.Fields{ - "query": q, - "error": err, - }).Error("Enumeration failed for query") + logger.With( + zap.String("query", q), + zap.Error(err), + ).Error("Enumeration failed for query") if errors.Is(err, githubsearch.ErrorUnableToListAllResult) { if *requireMinStarsFlag { os.Exit(1) @@ -133,31 +139,40 @@ func searchWorker(s *githubsearch.Searcher, logger *log.Entry, queries, results os.Exit(1) } } - logger.WithFields(log.Fields{ - "query": q, - "repo_count": total, - }).Info("Enumeration for query done") + logger.With( + zap.String("query", q), + zap.Int("repo_count", total), + ).Info("Enumeration for query done") } } func main() { envflag.Parse(envFlagMap) - logger := log.New() - logger.SetLevel(logLevel) + logger, err := log.NewLogger(logEnv, logLevel) + if err != nil { + panic(err) + } + defer logger.Sync() // roundtripper requires us to use the scorecard logger. - scLogger := sclog.NewLogrusLogger(logger) + innerLogger := zapr.NewLogger(logger) + scLogger := &sclog.Logger{Logger: &innerLogger} - // Ensure the -start date is not before the epoch. + // Warn if the -start date is before the epoch. if startDateFlag.Time().Before(epochDate) { - logger.Errorf("-start date must be no earlier than %s", epochDate.Format(githubDateFormat)) - os.Exit(2) + logger.With( + zap.String("start", startDateFlag.String()), + zap.String("epoch", epochDate.Format(githubDateFormat)), + ).Warn("-start date is before epoch") } // Ensure -start is before -end if endDateFlag.Time().Before(startDateFlag.Time()) { - logger.Error("-start date must be before -end date") + logger.With( + zap.String("start", startDateFlag.String()), + zap.String("end", endDateFlag.String()), + ).Error("-start date must be before -end date") os.Exit(2) } @@ -171,35 +186,33 @@ func main() { // Expand runIDToken into the runID inside the output file's name. if strings.Contains(outFilename, runIDToken) { runID := time.Now().UTC().Format(runIDDateFormat) - logger.WithFields(log.Fields{ - "run-id": runID, - }).Info("Using Run ID") + // Every future log message will have the run-id attached. + logger = logger.With(zap.String("run-id", runID)) + logger.Info("Using Run ID") outFilename = strings.ReplaceAll(outFilename, runIDToken, runID) } // Print a helpful message indicating the configuration we're using. - logger.WithFields(log.Fields{ - "filename": outFilename, - }).Info("Preparing output file") + logger.With( + zap.String("filename", outFilename), + ).Info("Preparing output file") // Open the output file out, err := outfile.Open(context.Background(), outFilename) if err != nil { // File failed to open - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to open output file") + logger.Error("Failed to open output file", zap.Error(err)) os.Exit(2) } defer out.Close() - logger.WithFields(log.Fields{ - "start": startDateFlag.String(), - "end": endDateFlag.String(), - "min_stars": *minStarsFlag, - "star_overlap": *starOverlapFlag, - "workers": *workersFlag, - }).Info("Starting enumeration") + logger.With( + zap.String("start", startDateFlag.String()), + zap.String("end", endDateFlag.String()), + zap.Int("min_stars", *minStarsFlag), + zap.Int("star_overlap", *starOverlapFlag), + zap.Int("workers", *workersFlag), + ).Info("Starting enumeration") // Track how long it takes to enumerate the repositories startTime := time.Now() @@ -218,7 +231,7 @@ func main() { // Start the worker goroutines to execute the search queries wait := workerpool.WorkerPool(*workersFlag, func(i int) { - workerLogger := logger.WithFields(log.Fields{"worker": i}) + workerLogger := logger.With(zap.Int("worker", i)) s := githubsearch.NewSearcher(ctx, client, workerLogger, githubsearch.PerPage(reposPerPage)) searchWorker(s, workerLogger, queries, results) }) @@ -236,9 +249,9 @@ func main() { // Work happens here. Iterate through the dates from today, until the start date. for created := endDateFlag.Time(); !startDateFlag.Time().After(created); created = created.Add(-oneDay) { - logger.WithFields(log.Fields{ - "created": created.Format(githubDateFormat), - }).Info("Scheduling day for enumeration") + logger.With( + zap.String("created", created.Format(githubDateFormat)), + ).Info("Scheduling day for enumeration") queries <- baseQuery + fmt.Sprintf(" created:%s", created.Format(githubDateFormat)) } logger.Debug("Waiting for workers to finish") @@ -253,8 +266,9 @@ func main() { // Wait for the writer to be finished. <-done - logger.WithFields(log.Fields{ - "total_repos": totalRepos, - "duration": time.Since(startTime).Truncate(time.Minute).String(), - }).Info("Finished enumeration") + logger.With( + zap.Int("total_repos", totalRepos), + zap.Duration("duration", time.Since(startTime).Truncate(time.Minute)), + zap.String("filename", outFilename), + ).Info("Finished enumeration") } diff --git a/go.mod b/go.mod index 6f6dc5c8..03256bcc 100644 --- a/go.mod +++ b/go.mod @@ -37,9 +37,11 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect github.com/aws/smithy-go v1.11.2 // indirect + github.com/blendle/zapdriver v1.3.1 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/zapr v1.2.3 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -55,6 +57,9 @@ require ( github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect github.com/stretchr/testify v1.8.0 // indirect go.opencensus.io v0.23.0 // indirect + go.uber.org/atomic v1.9.0 // indirect + go.uber.org/multierr v1.8.0 // indirect + go.uber.org/zap v1.23.0 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect diff --git a/go.sum b/go.sum index 167598dd..644562a0 100644 --- a/go.sum +++ b/go.sum @@ -166,6 +166,8 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4Nx github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= +github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 h1:tXKVfhE7FcSkhkv0UwkLvPDeZ4kz6OXd0PKPlFqf81M= @@ -225,8 +227,11 @@ github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3I github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= +github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= @@ -503,18 +508,24 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/multierr v1.8.0/go.mod h1:7EAYxJLBy9rStEaz58O2t4Uvip6FSURkq8/ppBp95ak= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA= go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= +go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= +go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= gocloud.dev v0.26.0 h1:4rM/SVL0lLs+rhC0Gmc+gt/82DBpb7nbpIZKXXnfMXg= gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= @@ -774,6 +785,7 @@ golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml index b1d410d6..2a9ad6b4 100644 --- a/infra/k8s/enumerate_github.yaml +++ b/infra/k8s/enumerate_github.yaml @@ -32,6 +32,8 @@ spec: env: - name: GITHUB_AUTH_SERVER value: "10.4.4.210:80" + - name: CRITICALITY_SCORE_LOG_ENV + value: "gcp" - name: CRITICALITY_SCORE_OUTFILE_FORCE value: "1" - name: CRITICALITY_SCORE_STARS_MIN From 6dd8af6ee07811232488aee6116d68aeb74ba10b Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 5 Sep 2022 11:42:57 +1000 Subject: [PATCH 095/172] Lower min stars for k8s to 50 (#183) Signed-off-by: Caleb Brown --- go.mod | 4 ++-- infra/k8s/enumerate_github.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 03256bcc..bf5c4500 100644 --- a/go.mod +++ b/go.mod @@ -4,11 +4,13 @@ go 1.18 require ( cloud.google.com/go/bigquery v1.32.0 + github.com/blendle/zapdriver v1.3.1 github.com/google/go-github/v44 v44.1.0 github.com/iancoleman/strcase v0.2.0 github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 github.com/sirupsen/logrus v1.8.1 + go.uber.org/zap v1.23.0 gocloud.dev v0.26.0 google.golang.org/api v0.88.0 gopkg.in/yaml.v3 v3.0.1 @@ -37,7 +39,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect github.com/aws/smithy-go v1.11.2 // indirect - github.com/blendle/zapdriver v1.3.1 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -59,7 +60,6 @@ require ( go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect - go.uber.org/zap v1.23.0 // indirect golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml index 2a9ad6b4..b51f4cbd 100644 --- a/infra/k8s/enumerate_github.yaml +++ b/infra/k8s/enumerate_github.yaml @@ -37,7 +37,7 @@ spec: - name: CRITICALITY_SCORE_OUTFILE_FORCE value: "1" - name: CRITICALITY_SCORE_STARS_MIN - value: "100" + value: "50" - name: CRITICALITY_SCORE_START_DATE value: "2021-01-01" - name: CRITICALITY_SCORE_END_DATE From 58d985ca72a1209b5e7edbcdc5c65c573689dc9a Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 5 Sep 2022 13:06:31 +1000 Subject: [PATCH 096/172] Woops. Forgot to add new log helper code. (#184) Signed-off-by: Caleb Brown --- internal/log/config.go | 39 ++++++++++++++++++++++++++++++ internal/log/env.go | 54 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 internal/log/config.go create mode 100644 internal/log/env.go diff --git a/internal/log/config.go b/internal/log/config.go new file mode 100644 index 00000000..f5157ab1 --- /dev/null +++ b/internal/log/config.go @@ -0,0 +1,39 @@ +package log + +import ( + "github.com/blendle/zapdriver" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" +) + +func dev() (zap.Config, []zap.Option) { + c := zap.NewDevelopmentConfig() + c.EncoderConfig.CallerKey = zapcore.OmitKey + // TODO, use go-isatty to choose color VS no-color + c.EncoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder + c.EncoderConfig.EncodeTime = zapcore.TimeEncoderOfLayout("2006-01-02 15:04:05.000") + return c, []zap.Option{} +} + +func gcp() (zap.Config, []zap.Option) { + c := zapdriver.NewProductionConfig() + // Make sure sampling is disabled. + c.Sampling = nil + // Build the logger and ensure we use the zapdriver Core so that labels + // are handled correctly. + return c, []zap.Option{zapdriver.WrapCore()} +} + +func NewLogger(e Env, l zapcore.Level) (*zap.Logger, error) { + var c zap.Config + var opts []zap.Option + switch e { + case GCPEnv: + c, opts = gcp() + default: + c, opts = dev() + } + + c.Level = zap.NewAtomicLevelAt(l) + return c.Build(opts...) +} diff --git a/internal/log/env.go b/internal/log/env.go new file mode 100644 index 00000000..32a4e922 --- /dev/null +++ b/internal/log/env.go @@ -0,0 +1,54 @@ +package log + +import "errors" + +type Env int + +const ( + UnknownEnv = Env(0) + DevEnv = Env(iota) + GCPEnv + + DefaultEnv = DevEnv +) + +var ErrorUnkownEnv = errors.New("unknown logging environment") + +// LookupEnv will return the instance of Env that corresponds to text. +// +// If text does not match a known environment UnknownEnv will be returned. +func LookupEnv(text string) Env { + switch text { + case "dev": + return DevEnv + case "gcp": + return GCPEnv + default: + return UnknownEnv + } +} + +func (e Env) String() string { + switch e { + case DevEnv: + return "dev" + case GCPEnv: + return "gcp" + default: + // panic? + return "unknown" + } +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (e *Env) UnmarshalText(text []byte) error { + *e = LookupEnv(string(text)) + if *e == UnknownEnv { + return ErrorUnkownEnv + } + return nil +} + +func (e Env) MarshalText() ([]byte, error) { + return []byte(e.String()), nil +} From 313bbfce53838773aef3106b73db8bb3ce3dbdd9 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 13 Sep 2022 11:20:27 +1000 Subject: [PATCH 097/172] Add a GitHub workflow that runs tests and linter. (#191) * Add a GitHub workflow that runs tests and linter. Signed-off-by: Caleb Brown * Tweak the CI workflow so the lint and test are in separate jobs. Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- .github/workflows/ci.yml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/ci.yml diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000..e947f0b3 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,27 @@ +name: "Continuous Integration" + +on: + pull_request: + +permissions: read-all + +jobs: + run-tests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 + - uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a + with: + go-version: 1.18 + - name: Run tests + run: make test + run-linter: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 + - name: Run linter + uses: github/super-linter@01d3218744765b55c3b5ffbb27e50961e50c33c5 + env: + VALIDATE_ALL_CODEBASE: false + DEFAULT_BRANCH: main + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 2180fd69e5ce66734c2bb0df25ca7508a2cf9128 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 19 Sep 2022 14:36:49 +1000 Subject: [PATCH 098/172] Add support for output enumerated urls in a scorecard compatible format. (#195) * Add support for output enumerated urls in a scorecard compatible format. Signed-off-by: Caleb Brown * Fix linter errors Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- cmd/enumerate_github/main.go | 7 +- cmd/enumerate_github/repowriter/scorecard.go | 33 +++++++ .../repowriter/scorecard_test.go | 25 ++++++ cmd/enumerate_github/repowriter/text.go | 22 +++++ cmd/enumerate_github/repowriter/text_test.go | 24 +++++ cmd/enumerate_github/repowriter/type.go | 66 ++++++++++++++ cmd/enumerate_github/repowriter/type_test.go | 90 +++++++++++++++++++ cmd/enumerate_github/repowriter/writer.go | 8 ++ go.mod | 6 +- go.sum | 17 +--- go.work.sum | 3 +- 11 files changed, 280 insertions(+), 21 deletions(-) create mode 100644 cmd/enumerate_github/repowriter/scorecard.go create mode 100644 cmd/enumerate_github/repowriter/scorecard_test.go create mode 100644 cmd/enumerate_github/repowriter/text.go create mode 100644 cmd/enumerate_github/repowriter/text_test.go create mode 100644 cmd/enumerate_github/repowriter/type.go create mode 100644 cmd/enumerate_github/repowriter/type_test.go create mode 100644 cmd/enumerate_github/repowriter/writer.go diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 4c569cfe..9d820b3f 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -33,6 +33,7 @@ import ( "go.uber.org/zap/zapcore" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" + "github.com/ossf/criticality_score/cmd/enumerate_github/repowriter" "github.com/ossf/criticality_score/internal/envflag" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" @@ -62,11 +63,13 @@ var ( endDateFlag = dateFlag(time.Now().UTC().Truncate(oneDay)) logLevel = defaultLogLevel logEnv log.Env + format repowriter.WriterType // Maps environment variables to the flags they correspond to. envFlagMap = envflag.Map{ "CRITICALITY_SCORE_LOG_ENV": "log-env", "CRITICALITY_SCORE_LOG_LEVEL": "log", + "CRITICALITY_SCORE_FORMAT": "format", "CRITICALITY_SCORE_WORKERS": "workers", "CRITICALITY_SCORE_START_DATE": "start", "CRITICALITY_SCORE_END_DATE": "end", @@ -103,6 +106,7 @@ func init() { flag.Var(&startDateFlag, "start", "the start `date` to enumerate back to. Must be at or after 2008-01-01.") flag.Var(&endDateFlag, "end", "the end `date` to enumerate from.") flag.Var(&logLevel, "log", "set the `level` of logging.") + textvarflag.TextVar(flag.CommandLine, &format, "format", repowriter.WriterTypeText, "set output file `format`.") textvarflag.TextVar(flag.CommandLine, &logEnv, "log-env", log.DefaultEnv, "set logging `env`.") outfile.DefineFlags(flag.CommandLine, "force", "append", "FILE") flag.Usage = func() { @@ -205,6 +209,7 @@ func main() { os.Exit(2) } defer out.Close() + w := format.New(out) logger.With( zap.String("start", startDateFlag.String()), @@ -241,7 +246,7 @@ func main() { totalRepos := 0 go func() { for repo := range results { - fmt.Fprintln(out, repo) + w.Write(repo) totalRepos++ } done <- true diff --git a/cmd/enumerate_github/repowriter/scorecard.go b/cmd/enumerate_github/repowriter/scorecard.go new file mode 100644 index 00000000..f80fc46e --- /dev/null +++ b/cmd/enumerate_github/repowriter/scorecard.go @@ -0,0 +1,33 @@ +package repowriter + +import ( + "encoding/csv" + "io" +) + +var header = []string{"repo", "metadata"} + +type scorecardWriter struct { + w *csv.Writer +} + +// Scorecard creates a new Writer instance that is used to write a csv file +// of repositories that is compatible with the github.com/ossf/scorecard +// project. +// +// The csv file has a header row with columns "repo" and "metadata". Each +// row consists of the repository url and blank metadata. +func Scorecard(w io.Writer) Writer { + csvWriter := csv.NewWriter(w) + csvWriter.Write(header) + return &scorecardWriter{w: csvWriter} +} + +// Write implements the Writer interface. +func (w *scorecardWriter) Write(repo string) error { + if err := w.w.Write([]string{repo, ""}); err != nil { + return err + } + w.w.Flush() + return w.w.Error() +} diff --git a/cmd/enumerate_github/repowriter/scorecard_test.go b/cmd/enumerate_github/repowriter/scorecard_test.go new file mode 100644 index 00000000..0a5baa4b --- /dev/null +++ b/cmd/enumerate_github/repowriter/scorecard_test.go @@ -0,0 +1,25 @@ +package repowriter_test + +import ( + "bytes" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/ossf/criticality_score/cmd/enumerate_github/repowriter" +) + +func TestScorecardRepoWriter(t *testing.T) { + var buf bytes.Buffer + w := repowriter.Scorecard(&buf) + w.Write("https://github.com/example/example") + w.Write("https://github.com/ossf/criticality_score") + + want := "repo,metadata\n" + + "https://github.com/example/example,\n" + + "https://github.com/ossf/criticality_score,\n" + + if diff := cmp.Diff(want, buf.String()); diff != "" { + t.Fatalf("Scorecard() mismatch (-want +got):\n%s", diff) + } +} diff --git a/cmd/enumerate_github/repowriter/text.go b/cmd/enumerate_github/repowriter/text.go new file mode 100644 index 00000000..6cd46d8e --- /dev/null +++ b/cmd/enumerate_github/repowriter/text.go @@ -0,0 +1,22 @@ +package repowriter + +import ( + "fmt" + "io" +) + +type textWriter struct { + w io.Writer +} + +// Text creates a new Writer instance that is used to write a simple text file +// of repositories, where each line has a single repository url. +func Text(w io.Writer) Writer { + return &textWriter{w} +} + +// Write implements the Writer interface. +func (w *textWriter) Write(repo string) error { + _, err := fmt.Fprintln(w.w, repo) + return err +} diff --git a/cmd/enumerate_github/repowriter/text_test.go b/cmd/enumerate_github/repowriter/text_test.go new file mode 100644 index 00000000..52e615b2 --- /dev/null +++ b/cmd/enumerate_github/repowriter/text_test.go @@ -0,0 +1,24 @@ +package repowriter_test + +import ( + "bytes" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/ossf/criticality_score/cmd/enumerate_github/repowriter" +) + +func TestTextRepoWriter(t *testing.T) { + var buf bytes.Buffer + w := repowriter.Text(&buf) + w.Write("https://github.com/example/example") + w.Write("https://github.com/ossf/criticality_score") + + want := "https://github.com/example/example\n" + + "https://github.com/ossf/criticality_score\n" + + if diff := cmp.Diff(want, buf.String()); diff != "" { + t.Fatalf("Text() mismatch (-want +got):\n%s", diff) + } +} diff --git a/cmd/enumerate_github/repowriter/type.go b/cmd/enumerate_github/repowriter/type.go new file mode 100644 index 00000000..792c1907 --- /dev/null +++ b/cmd/enumerate_github/repowriter/type.go @@ -0,0 +1,66 @@ +package repowriter + +import ( + "bytes" + "errors" + "io" +) + +type WriterType int + +const ( + // WriterTypeText corresponds to the Writer returned by Text. + WriterTypeText = WriterType(iota) + + // WriterTypeScorecard corresponds to the Writer returned by Scorecard. + WriterTypeScorecard +) + +var ErrorUnknownRepoWriterType = errors.New("unknown repo writer type") + +// String implements the fmt.Stringer interface. +func (t WriterType) String() string { + text, err := t.MarshalText() + if err != nil { + return "" + } + return string(text) +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (t WriterType) MarshalText() ([]byte, error) { + switch t { + case WriterTypeText: + return []byte("text"), nil + case WriterTypeScorecard: + return []byte("scorecard"), nil + default: + return []byte{}, ErrorUnknownRepoWriterType + } +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (t *WriterType) UnmarshalText(text []byte) error { + switch { + case bytes.Equal(text, []byte("text")): + *t = WriterTypeText + case bytes.Equal(text, []byte("scorecard")): + *t = WriterTypeScorecard + default: + return ErrorUnknownRepoWriterType + } + return nil +} + +// New will return a new instance of the corresponding implementation of +// Writer for the given WriterType. +func (t *WriterType) New(w io.Writer) Writer { + switch *t { + case WriterTypeText: + return Text(w) + case WriterTypeScorecard: + return Scorecard(w) + default: + return nil + } +} diff --git a/cmd/enumerate_github/repowriter/type_test.go b/cmd/enumerate_github/repowriter/type_test.go new file mode 100644 index 00000000..3ab4ad8f --- /dev/null +++ b/cmd/enumerate_github/repowriter/type_test.go @@ -0,0 +1,90 @@ +package repowriter_test + +import ( + "errors" + "testing" + + "github.com/ossf/criticality_score/cmd/enumerate_github/repowriter" +) + +func TestTypeString(t *testing.T) { + //nolint:govet + tests := []struct { + name string + writerType repowriter.WriterType + want string + }{ + {name: "text", writerType: repowriter.WriterTypeText, want: "text"}, + {name: "scorecard", writerType: repowriter.WriterTypeScorecard, want: "scorecard"}, + {name: "unknown", writerType: repowriter.WriterType(10), want: ""}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.writerType.String() + if got != test.want { + t.Fatalf("String() == %s, want %s", got, test.want) + } + }) + } +} + +func TestTypeMarshalText(t *testing.T) { + //nolint:govet + tests := []struct { + name string + writerType repowriter.WriterType + want string + err error + }{ + {name: "text", writerType: repowriter.WriterTypeText, want: "text"}, + {name: "scorecard", writerType: repowriter.WriterTypeScorecard, want: "scorecard"}, + {name: "unknown", writerType: repowriter.WriterType(10), want: "", err: repowriter.ErrorUnknownRepoWriterType}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.writerType.MarshalText() + if err != nil && !errors.Is(err, test.err) { + t.Fatalf("MarhsalText() == %v, want %v", err, test.err) + } + if err == nil { + if test.err != nil { + t.Fatalf("MarshalText() return nil error, want %v", test.err) + } + if string(got) != test.want { + t.Fatalf("MarhsalText() == %s, want %s", got, test.want) + } + } + }) + } +} + +func TestTypeUnmarshalText(t *testing.T) { + //nolint:govet + tests := []struct { + input string + want repowriter.WriterType + err error + }{ + {input: "text", want: repowriter.WriterTypeText}, + {input: "scorecard", want: repowriter.WriterTypeScorecard}, + {input: "", want: 0, err: repowriter.ErrorUnknownRepoWriterType}, + {input: "unknown", want: 0, err: repowriter.ErrorUnknownRepoWriterType}, + } + for _, test := range tests { + t.Run(test.input, func(t *testing.T) { + var got repowriter.WriterType + err := got.UnmarshalText([]byte(test.input)) + if err != nil && !errors.Is(err, test.err) { + t.Fatalf("UnmarshalText() == %v, want %v", err, test.err) + } + if err == nil { + if test.err != nil { + t.Fatalf("MarshalText() return nil error, want %v", test.err) + } + if got != test.want { + t.Fatalf("UnmarshalText() parsed %d, want %d", int(got), int(test.want)) + } + } + }) + } +} diff --git a/cmd/enumerate_github/repowriter/writer.go b/cmd/enumerate_github/repowriter/writer.go new file mode 100644 index 00000000..b0f7f84d --- /dev/null +++ b/cmd/enumerate_github/repowriter/writer.go @@ -0,0 +1,8 @@ +package repowriter + +// Writer is a simple interface for writing a repo. This interface is to +// abstract output formats for lists of repository urls. +type Writer interface { + // Write outputs a single repository url. + Write(repo string) error +} diff --git a/go.mod b/go.mod index bf5c4500..c8c57415 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,8 @@ go 1.18 require ( cloud.google.com/go/bigquery v1.32.0 github.com/blendle/zapdriver v1.3.1 + github.com/go-logr/zapr v1.2.3 + github.com/google/go-cmp v0.5.8 github.com/google/go-github/v44 v44.1.0 github.com/iancoleman/strcase v0.2.0 github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 @@ -42,21 +44,17 @@ require ( github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect github.com/go-logr/logr v1.2.3 // indirect - github.com/go-logr/zapr v1.2.3 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-cmp v0.5.8 // indirect github.com/google/go-github/v41 v41.0.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/google/wire v0.5.0 // indirect github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect github.com/googleapis/gax-go/v2 v2.4.0 // indirect - github.com/googleapis/go-type-adapters v1.0.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect - github.com/stretchr/testify v1.8.0 // indirect go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect diff --git a/go.sum b/go.sum index 644562a0..a93f6b88 100644 --- a/go.sum +++ b/go.sum @@ -28,7 +28,6 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= -cloud.google.com/go v0.100.2 h1:t9Iw5QH5v4XtlEQaCtUY7x6sCABps8sW0acw7e2WQ6Y= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= cloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0= @@ -46,7 +45,6 @@ cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= @@ -75,7 +73,6 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= -cloud.google.com/go/storage v1.22.0 h1:NUV0NNp9nkBuW66BFRLuMgldN60C57ET3dhbwLIYio8= cloud.google.com/go/storage v1.22.0/go.mod h1:GbaLEoMqbVm6sx3Z0R++gSiBlgMv6yUi2q1DeGFKQgE= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= cloud.google.com/go/storage v1.25.0 h1:D2Dn0PslpK7Z3B2AvuUHyIC762bDbGJdlmQlCBR71os= @@ -165,6 +162,7 @@ github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 h1:cJGRyzCSVwZC7zZZ1xbx9m32UnrK github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= @@ -350,11 +348,9 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0 h1:nRJtk3y8Fm770D42QV6T90ZnvFZyk7agSo3Q+Z9p3WI= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= @@ -451,6 +447,7 @@ github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 h1:Db6m7J/xaIt github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4/go.mod h1:PbooSR+65A6HA+eoJ7ICwek/muANHZsR08QV24tuiKA= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= @@ -475,16 +472,13 @@ github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasO github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -511,6 +505,7 @@ go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= @@ -652,7 +647,6 @@ golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0= @@ -830,7 +824,6 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= @@ -876,7 +869,6 @@ google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7 google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0 h1:0AYh/ae6l9TDUvIQrDw5QRpM100P6oHgD+o3dYHMzJg= google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= @@ -982,8 +974,6 @@ google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd h1:e0TwkXOdbnH/1x5rc5MZ/VYyiZ4v+RdVfrGMqEwT68I= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= @@ -1020,7 +1010,6 @@ google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2 h1:u+MLGgVf7vRdjEYZ8wDFhAVNmhkbJ5hmrA1LMWK1CAQ= google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= diff --git a/go.work.sum b/go.work.sum index 523e3455..63323c46 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,3 +1,4 @@ +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= @@ -11,8 +12,6 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= -go.uber.org/multierr v1.8.0 h1:dg6GjLku4EH+249NNmoIciG9N/jURbDG+pFlTkhzIC8= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= From 4a456d9b414ab3c81b880842b8fcfbcad067ab47 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 15:45:22 +1000 Subject: [PATCH 099/172] Bump actions/setup-go from 3.2.1 to 3.3.0 (#192) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3.2.1 to 3.3.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/84cbf8094393cdc5fe1fe1671ff2647332956b1a...268d8c0ca0432bb2cf416faae41297df9d262d7f) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e947f0b3..b664ee09 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -10,7 +10,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - - uses: actions/setup-go@84cbf8094393cdc5fe1fe1671ff2647332956b1a + - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f with: go-version: 1.18 - name: Run tests From 6c644fb61942cba25b75f7507405de8d1cfc179d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 19 Sep 2022 15:52:06 +1000 Subject: [PATCH 100/172] Bump ossf/scorecard-action from 2.0.0.pre.alpha.2 to 2.0.3 (#190) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.0.0.pre.alpha.2 to 2.0.3. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/08dd0cebb088ac0fd6364339b1b3b68b75041ea8...865b4092859256271290c77adbd10a43f4779972) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index b889fedb..830b51d1 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -21,7 +21,7 @@ jobs: - name: "Checkout code" uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b - name: "Run analysis" - uses: ossf/scorecard-action@08dd0cebb088ac0fd6364339b1b3b68b75041ea8 # v2.0.0-alpha.2 + uses: ossf/scorecard-action@865b4092859256271290c77adbd10a43f4779972 # v2.0.0-alpha.2 with: results_file: results.sarif results_format: sarif From 3573f2296505de34d0fb75b5da57bdef5d3a15ed Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 20 Sep 2022 12:43:17 +1000 Subject: [PATCH 101/172] Migrate the collect_signals tool over to zap for logging. (#196) * Migrate the collect_signals tool over to zap for logging. Signed-off-by: Caleb Brown * Fix import order. Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- cmd/collect_signals/depsdev/collector.go | 8 +- cmd/collect_signals/depsdev/dependents.go | 14 +-- cmd/collect_signals/github/factory.go | 8 +- cmd/collect_signals/github/repo.go | 4 +- cmd/collect_signals/main.go | 101 ++++++++++++---------- internal/githubapi/roundtripper.go | 25 +++--- internal/githubapi/roundtripper_test.go | 43 +++++---- 7 files changed, 104 insertions(+), 99 deletions(-) diff --git a/cmd/collect_signals/depsdev/collector.go b/cmd/collect_signals/depsdev/collector.go index 59a03213..f0d9b876 100644 --- a/cmd/collect_signals/depsdev/collector.go +++ b/cmd/collect_signals/depsdev/collector.go @@ -20,7 +20,7 @@ import ( "strings" "cloud.google.com/go/bigquery" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" "github.com/ossf/criticality_score/cmd/collect_signals/collector" "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" @@ -41,7 +41,7 @@ func (s *depsDevSet) Namespace() signal.Namespace { } type depsDevCollector struct { - logger *log.Logger + logger *zap.Logger dependents *dependents } @@ -60,7 +60,7 @@ func (c *depsDevCollector) Collect(ctx context.Context, r projectrepo.Repo) (sig if t == "" { return &s, nil } - c.logger.WithField("url", r.URL().String()).Debug("Fetching deps.dev dependent count") + c.logger.With(zap.String("url", r.URL().String())).Debug("Fetching deps.dev dependent count") deps, found, err := c.dependents.Count(ctx, n, t) if err != nil { return nil, err @@ -76,7 +76,7 @@ func (c *depsDevCollector) Collect(ctx context.Context, r projectrepo.Repo) (sig // TODO add options to configure the dataset: // - force dataset re-creation (-update-strategy = always,stale,weekly,monthly,never) // - force dataset destruction (-depsdev-destroy-data) -func NewCollector(ctx context.Context, logger *log.Logger, projectID, datasetName string) (collector.Collector, error) { +func NewCollector(ctx context.Context, logger *zap.Logger, projectID, datasetName string) (collector.Collector, error) { if projectID == "" { projectID = bigquery.DetectProjectID } diff --git a/cmd/collect_signals/depsdev/dependents.go b/cmd/collect_signals/depsdev/dependents.go index 3ea95534..c6bc1901 100644 --- a/cmd/collect_signals/depsdev/dependents.go +++ b/cmd/collect_signals/depsdev/dependents.go @@ -22,7 +22,7 @@ import ( "time" "cloud.google.com/go/bigquery" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" _ "google.golang.org/api/bigquery/v2" ) @@ -66,14 +66,14 @@ FROM ` + "`{{.ProjectID}}.{{.DatasetName}}.{{.TableName}}`" + ` WHERE ProjectName = @projectname AND ProjectType = @projecttype; ` -func NewDependents(ctx context.Context, client *bigquery.Client, logger *log.Logger, datasetName string) (*dependents, error) { +func NewDependents(ctx context.Context, client *bigquery.Client, logger *zap.Logger, datasetName string) (*dependents, error) { b := &bq{client: client} c := &dependents{ b: b, - logger: logger.WithFields(log.Fields{ - "project_id": b.Project(), - "dataset": datasetName, - }), + logger: logger.With( + zap.String("project_id", b.Project()), + zap.String("dataset", datasetName), + ), datasetName: datasetName, } var err error @@ -113,7 +113,7 @@ func NewDependents(ctx context.Context, client *bigquery.Client, logger *log.Log type dependents struct { b bqAPI - logger *log.Entry + logger *zap.Logger snapshotTime time.Time countQuery string datasetName string diff --git a/cmd/collect_signals/github/factory.go b/cmd/collect_signals/github/factory.go index 2f39187d..cd8803a3 100644 --- a/cmd/collect_signals/github/factory.go +++ b/cmd/collect_signals/github/factory.go @@ -18,7 +18,7 @@ import ( "context" "net/url" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/internal/githubapi" @@ -26,10 +26,10 @@ import ( type factory struct { client *githubapi.Client - logger *log.Logger + logger *zap.Logger } -func NewRepoFactory(client *githubapi.Client, logger *log.Logger) projectrepo.Factory { +func NewRepoFactory(client *githubapi.Client, logger *zap.Logger) projectrepo.Factory { return &factory{ client: client, logger: logger, @@ -40,7 +40,7 @@ func (f *factory) New(ctx context.Context, u *url.URL) (projectrepo.Repo, error) p := &repo{ client: f.client, origURL: u, - logger: f.logger.WithField("url", u), + logger: f.logger.With(zap.String("url", u.String())), } if err := p.init(ctx); err != nil { return nil, err diff --git a/cmd/collect_signals/github/repo.go b/cmd/collect_signals/github/repo.go index 4464ecb3..8bf11dc9 100644 --- a/cmd/collect_signals/github/repo.go +++ b/cmd/collect_signals/github/repo.go @@ -19,7 +19,7 @@ import ( "net/url" "time" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" "github.com/ossf/criticality_score/cmd/collect_signals/github/legacy" "github.com/ossf/criticality_score/internal/githubapi" @@ -29,7 +29,7 @@ import ( type repo struct { client *githubapi.Client origURL *url.URL - logger *log.Entry + logger *zap.Logger BasicData *basicRepoData realURL *url.URL diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 1dd0b196..ccfb6944 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -26,9 +26,11 @@ import ( "path" "strings" + "github.com/go-logr/zapr" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" sclog "github.com/ossf/scorecard/v4/log" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" "github.com/ossf/criticality_score/cmd/collect_signals/collector" "github.com/ossf/criticality_score/cmd/collect_signals/depsdev" @@ -37,23 +39,26 @@ import ( "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/cmd/collect_signals/result" "github.com/ossf/criticality_score/internal/githubapi" + log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" ) -const defaultLogLevel = log.InfoLevel +const defaultLogLevel = zapcore.InfoLevel var ( gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") depsdevDatasetFlag = flag.String("depsdev-dataset", depsdev.DefaultDatasetName, "the BigQuery dataset name to use.") workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") - logLevel log.Level + logLevel = defaultLogLevel + logEnv log.Env ) func init() { - textvarflag.TextVar(flag.CommandLine, &logLevel, "log", defaultLogLevel, "set the `level` of logging.") + flag.Var(&logLevel, "log", "set the `level` of logging.") + textvarflag.TextVar(flag.CommandLine, &logEnv, "log-env", log.DefaultEnv, "set logging `env`.") outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -67,17 +72,15 @@ func init() { } } -func handleRepo(ctx context.Context, logger *log.Entry, u *url.URL, out result.Writer) { +func handleRepo(ctx context.Context, logger *zap.Logger, u *url.URL, out result.Writer) { r, err := projectrepo.Resolve(ctx, u) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Warning("Failed to create project") + logger.With(zap.Error(err)).Warn("Failed to create project") // TODO: we should have an error that indicates that the URL/Project // should be skipped/ignored. return // TODO: add a flag to continue or abort on failure } - logger = logger.WithField("canonical_url", r.URL().String()) + logger = logger.With(zap.String("canonical_url", r.URL().String())) // TODO: p.URL() should be checked to see if it has already been processed. @@ -85,25 +88,25 @@ func handleRepo(ctx context.Context, logger *log.Entry, u *url.URL, out result.W logger.Info("Collecting") ss, err := collector.Collect(ctx, r) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to collect signals for project") + logger.With( + zap.Error(err), + ).Error("Failed to collect signals for project") os.Exit(1) // TODO: add a flag to continue or abort on failure } rec := out.Record() for _, s := range ss { if err := rec.WriteSignalSet(s); err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to write signal set") + logger.With( + zap.Error(err), + ).Error("Failed to write signal set") os.Exit(1) // TODO: add a flag to continue or abort on failure } } if err := rec.Done(); err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to complete record") + logger.With( + zap.Error(err), + ).Error("Failed to complete record") os.Exit(1) // TODO: add a flag to continue or abort on failure } } @@ -111,11 +114,15 @@ func handleRepo(ctx context.Context, logger *log.Entry, u *url.URL, out result.W func main() { flag.Parse() - logger := log.New() - logger.SetLevel(logLevel) + logger, err := log.NewLogger(logEnv, logLevel) + if err != nil { + panic(err) + } + defer logger.Sync() // roundtripper requires us to use the scorecard logger. - scLogger := sclog.NewLogrusLogger(logger) + innerLogger := zapr.NewLogger(logger) + scLogger := &sclog.Logger{Logger: &innerLogger} if flag.NArg() < 2 { logger.Error("Must have at least one input file and an output file specified.") @@ -134,15 +141,15 @@ func main() { readers = append(readers, os.Stdin) continue } - logger.WithFields(log.Fields{ - "filename": inFilename, - }).Debug("Reading from file") + logger.With( + zap.String("filename", inFilename), + ).Debug("Reading from file") f, err := os.Open(inFilename) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "filename": inFilename, - }).Error("Failed to open an input file") + logger.With( + zap.String("filename", inFilename), + zap.Error(err), + ).Error("Failed to open an input file") os.Exit(2) } defer f.Close() @@ -154,10 +161,10 @@ func main() { outFilename := flag.Args()[lastArg] w, err := outfile.Open(context.Background(), outFilename) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "filename": outFilename, - }).Error("Failed to open file for output") + logger.With( + zap.String("filename", outFilename), + zap.Error(err), + ).Error("Failed to open file for output") os.Exit(2) } defer w.Close() @@ -188,9 +195,9 @@ func main() { } else { ddcollector, err := depsdev.NewCollector(ctx, logger, *gcpProjectFlag, *depsdevDatasetFlag) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to create deps.dev collector") + logger.With( + zap.Error(err), + ).Error("Failed to create deps.dev collector") os.Exit(2) } logger.Info("deps.dev signal collector enabled") @@ -203,9 +210,9 @@ func main() { // Start the workers that process a channel of repo urls. repos := make(chan *url.URL) wait := workerpool.WorkerPool(*workersFlag, func(worker int) { - innerLogger := logger.WithField("worker", worker) + innerLogger := logger.With(zap.Int("worker", worker)) for u := range repos { - handleRepo(ctx, innerLogger.WithField("url", u.String()), u, out) + handleRepo(ctx, innerLogger.With(zap.String("url", u.String())), u, out) } }) @@ -216,23 +223,23 @@ func main() { u, err := url.Parse(strings.TrimSpace(line)) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "url": line, - }).Error("Failed to parse project url") + logger.With( + zap.String("url", line), + zap.Error(err), + ).Error("Failed to parse project url") os.Exit(1) // TODO: add a flag to continue or abort on failure } - logger.WithFields(log.Fields{ - "url": u.String(), - }).Debug("Parsed project url") + logger.With( + zap.String("url", u.String()), + ).Debug("Parsed project url") // Send the url to the workers repos <- u } if err := scanner.Err(); err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed while reading input") + logger.With( + zap.Error(err), + ).Error("Failed while reading input") os.Exit(2) } // Close the repos channel to indicate that there is no more input. diff --git a/internal/githubapi/roundtripper.go b/internal/githubapi/roundtripper.go index 99953445..6d626f22 100644 --- a/internal/githubapi/roundtripper.go +++ b/internal/githubapi/roundtripper.go @@ -25,7 +25,7 @@ import ( "time" "github.com/google/go-github/v44/github" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" "github.com/ossf/criticality_score/internal/retry" ) @@ -39,7 +39,7 @@ var ( issueCommentsRe = regexp.MustCompile("^repos/[^/]+/[^/]+/issues/comments$") ) -func NewRoundTripper(rt http.RoundTripper, logger *log.Logger) http.RoundTripper { +func NewRoundTripper(rt http.RoundTripper, logger *zap.Logger) http.RoundTripper { s := &strategies{logger: logger} return retry.NewRoundTripper(rt, retry.InitialDelay(2*time.Minute), @@ -51,7 +51,7 @@ func NewRoundTripper(rt http.RoundTripper, logger *log.Logger) http.RoundTripper } type strategies struct { - logger *log.Logger + logger *zap.Logger } func respBodyContains(r *http.Response, search string) (bool, error) { @@ -69,7 +69,7 @@ func (s *strategies) ServerError(r *http.Response) (retry.RetryStrategy, error) if r.StatusCode < 500 || 600 <= r.StatusCode { return retry.NoRetry, nil } - s.logger.WithField("status", r.Status).Warn("5xx: detected") + s.logger.With(zap.String("status", r.Status)).Warn("5xx: detected") path := strings.Trim(r.Request.URL.Path, "/") if issuesRe.MatchString(path) { s.logger.Warn("Ignoring /repos/X/Y/issues url.") @@ -115,11 +115,10 @@ func (s *strategies) SecondaryRateLimit(r *http.Response) (retry.RetryStrategy, r.Body.Close() r.Body = io.NopCloser(bytes.NewBuffer(data)) if err != nil || data == nil { - s.logger.WithFields( - log.Fields{ - "error": err, - "data_nil": (data == nil), - }).Warn("ReadAll failed.") + s.logger.With( + zap.Error(err), + zap.Bool("data_nil", data == nil), + ).Warn("ReadAll failed.") return retry.NoRetry, err } // Don't error check the unmarshall - if there is an error and the parsing @@ -128,10 +127,10 @@ func (s *strategies) SecondaryRateLimit(r *http.Response) (retry.RetryStrategy, // will cause the response to be processed again by go-github with an error // being generated there. json.Unmarshal(data, errorResponse) - s.logger.WithFields(log.Fields{ - "url": errorResponse.DocumentationURL, - "message": errorResponse.Message, - }).Warn("Error response data") + s.logger.With( + zap.String("url", errorResponse.DocumentationURL), + zap.String("message", errorResponse.Message), + ).Warn("Error response data") if strings.HasSuffix(errorResponse.DocumentationURL, "#abuse-rate-limits") || strings.HasSuffix(errorResponse.DocumentationURL, "#secondary-rate-limits") { s.logger.Warn("Secondary rate limit hit.") diff --git a/internal/githubapi/roundtripper_test.go b/internal/githubapi/roundtripper_test.go index 4a316742..dc7bbc71 100644 --- a/internal/githubapi/roundtripper_test.go +++ b/internal/githubapi/roundtripper_test.go @@ -24,7 +24,7 @@ import ( "testing" "time" - log "github.com/sirupsen/logrus" + "go.uber.org/zap/zaptest" "github.com/ossf/criticality_score/internal/retry" ) @@ -34,10 +34,9 @@ const ( testSecondaryRateLimitDocURL = "https://docs.github.com/en/rest/overview/resources-in-the-rest-api#secondary-rate-limits" ) -func newTestStrategies() *strategies { - logger := log.New() - logger.Out = io.Discard - return &strategies{logger: logger} +func newTestStrategies(t *testing.T) *strategies { + t.Helper() + return &strategies{logger: zaptest.NewLogger(t)} } type readerFn func(p []byte) (n int, err error) @@ -49,27 +48,27 @@ func (r readerFn) Read(p []byte) (n int, err error) { func TestRetryAfter(t *testing.T) { r := &http.Response{Header: http.Header{http.CanonicalHeaderKey("Retry-After"): {"123"}}} - if d := newTestStrategies().RetryAfter(r); d != 123*time.Second { + if d := newTestStrategies(t).RetryAfter(r); d != 123*time.Second { t.Fatalf("RetryAfter() == %d, want %v", d, 123*time.Second) } } func TestRetryAfter_NoHeader(t *testing.T) { - if d := newTestStrategies().RetryAfter(&http.Response{}); d != 0 { + if d := newTestStrategies(t).RetryAfter(&http.Response{}); d != 0 { t.Fatalf("RetryAfter() == %d, want 0", d) } } func TestRetryAfter_InvalidTime(t *testing.T) { r := &http.Response{Header: http.Header{http.CanonicalHeaderKey("Retry-After"): {"junk"}}} - if d := newTestStrategies().RetryAfter(r); d != 0 { + if d := newTestStrategies(t).RetryAfter(r); d != 0 { t.Fatalf("RetryAfter() == %d, want 0", d) } } func TestRetryAfter_ZeroTime(t *testing.T) { r := &http.Response{Header: http.Header{http.CanonicalHeaderKey("Retry-After"): {"0"}}} - if d := newTestStrategies().RetryAfter(r); d != 0 { + if d := newTestStrategies(t).RetryAfter(r); d != 0 { t.Fatalf("RetryAfter() == %d, want 0", d) } } @@ -80,7 +79,7 @@ func TestServerError(t *testing.T) { Request: &http.Request{URL: u}, StatusCode: http.StatusInternalServerError, } - s, err := newTestStrategies().ServerError(r) + s, err := newTestStrategies(t).ServerError(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } @@ -95,7 +94,7 @@ func TestServerError_IssueComments(t *testing.T) { Request: &http.Request{URL: u}, StatusCode: http.StatusInternalServerError, } - s, err := newTestStrategies().ServerError(r) + s, err := newTestStrategies(t).ServerError(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } @@ -130,7 +129,7 @@ func TestServerError_StatusCodes(t *testing.T) { Request: &http.Request{URL: u}, StatusCode: test.statusCode, } - s, _ := newTestStrategies().ServerError(r) + s, _ := newTestStrategies(t).ServerError(r) if s != test.strategy { t.Fatalf("ServerError() == %v, want %v", s, test.strategy) } @@ -144,7 +143,7 @@ func TestServerError400(t *testing.T) { StatusCode: http.StatusBadRequest, Body: io.NopCloser(bytes.NewBuffer([]byte(`This is an error`))), } - s, err := newTestStrategies().ServerError400(r) + s, err := newTestStrategies(t).ServerError400(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } @@ -159,7 +158,7 @@ func TestServerError400_NoMatchingString(t *testing.T) { StatusCode: http.StatusBadRequest, Body: io.NopCloser(bytes.NewBuffer([]byte(`Web PageThis is an error`))), } - s, err := newTestStrategies().ServerError400(r) + s, err := newTestStrategies(t).ServerError400(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } @@ -244,7 +243,7 @@ func TestSecondaryRateLimit(t *testing.T) { Body: io.NopCloser(bytes.NewBuffer( []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL)))), } - s, err := newTestStrategies().SecondaryRateLimit(r) + s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } @@ -259,7 +258,7 @@ func TestSecondaryRateLimit_AbuseUrl(t *testing.T) { Body: io.NopCloser(bytes.NewBuffer( []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testAbuseRateLimitDocURL)))), } - s, err := newTestStrategies().SecondaryRateLimit(r) + s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } @@ -273,7 +272,7 @@ func TestSecondaryRateLimit_OtherUrl(t *testing.T) { StatusCode: http.StatusForbidden, Body: io.NopCloser(bytes.NewBuffer([]byte(`{"message": "test", "documentation_url": "https://example.org/"}`))), } - s, err := newTestStrategies().SecondaryRateLimit(r) + s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } @@ -290,7 +289,7 @@ func TestSecondaryRateLimit_BodyError(t *testing.T) { return 0, want })), } - _, err := newTestStrategies().SecondaryRateLimit(r) + _, err := newTestStrategies(t).SecondaryRateLimit(r) if err == nil { t.Fatalf("ServerError() returned no error, want %v", want) } @@ -326,7 +325,7 @@ func TestSecondaryRateLimit_StatusCodes(t *testing.T) { Body: io.NopCloser(bytes.NewBuffer( []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL)))), } - s, err := newTestStrategies().SecondaryRateLimit(r) + s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { t.Fatalf("ServerError() errored %v, want no error", err) } From 477ecf2343de6c6c445b55321420ad6bf4f258c5 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 20 Sep 2022 13:32:33 +1000 Subject: [PATCH 102/172] Switch to golangci-lint-action instead of super-linter (#197) * Always validate the entire codebase. Signed-off-by: Caleb Brown * Switch to golangci-lint action as super-linter has issues with Go. Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- .github/workflows/ci.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b664ee09..14dadd5a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,9 @@ name: "Continuous Integration" on: + push: + branches: + - main pull_request: permissions: read-all @@ -19,9 +22,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - - name: Run linter - uses: github/super-linter@01d3218744765b55c3b5ffbb27e50961e50c33c5 - env: - VALIDATE_ALL_CODEBASE: false - DEFAULT_BRANCH: main - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f + with: + go-version: 1.18 + - name: golangci-lint + uses: golangci/golangci-lint-action@537aa1903e5d359d0b27dbc19ddd22c5087f3fbc From 20ced714cc775c41b7f7fa933608dacaab685f53 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 20 Sep 2022 18:46:26 +1000 Subject: [PATCH 103/172] Remove last of logrus usage (#198) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- cmd/scorer/main.go | 95 +++++++++++++++++-------------- go.mod | 3 +- internal/textvarflag/flag_test.go | 4 +- 3 files changed, 54 insertions(+), 48 deletions(-) diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index 86b17d90..f8dd7726 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -45,23 +45,27 @@ import ( "strconv" "strings" - log "github.com/sirupsen/logrus" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" _ "github.com/ossf/criticality_score/cmd/scorer/algorithm/wam" + log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/textvarflag" ) -const defaultLogLevel = log.InfoLevel +const defaultLogLevel = zapcore.InfoLevel var ( configFlag = flag.String("config", "", "the filename of the config (required)") columnNameFlag = flag.String("column", "", "the name of the output column") - logLevel log.Level + logLevel = defaultLogLevel + logEnv log.Env ) func init() { - textvarflag.TextVar(flag.CommandLine, &logLevel, "log", defaultLogLevel, "set the `level` of logging.") + flag.Var(&logLevel, "log", "set the `level` of logging.") + textvarflag.TextVar(flag.CommandLine, &logEnv, "log-env", log.DefaultEnv, "set logging `env`.") outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") // TODO: add the ability to disable "append" flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -117,8 +121,11 @@ func makeRecord(header, row []string) map[string]float64 { func main() { flag.Parse() - logger := log.New() - logger.SetLevel(logLevel) + logger, err := log.NewLogger(logEnv, logLevel) + if err != nil { + panic(err) + } + defer logger.Sync() if flag.NArg() != 2 { logger.Error("Must have an input file and an output file specified") @@ -133,15 +140,15 @@ func main() { logger.Info("Reading from stdin") r = csv.NewReader(os.Stdin) } else { - logger.WithFields(log.Fields{ - "filename": inFilename, - }).Debug("Reading from file") + logger.With( + zap.String("filename", inFilename), + ).Debug("Reading from file") f, err := os.Open(inFilename) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "filename": inFilename, - }).Error("Failed to open input file") + logger.With( + zap.Error(err), + zap.String("filename", inFilename), + ).Error("Failed to open input file") os.Exit(2) } defer f.Close() @@ -151,10 +158,10 @@ func main() { // Open the out-file for writing f, err := outfile.Open(context.Background(), outFilename) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "filename": outFilename, - }).Error("Failed to open file for output") + logger.With( + zap.Error(err), + zap.String("filename", outFilename), + ).Error("Failed to open file for output") os.Exit(2) } defer f.Close() @@ -169,49 +176,49 @@ func main() { cf, err := os.Open(*configFlag) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "filename": configFlag, - }).Error("Failed to open config file") + logger.With( + zap.Error(err), + zap.String("filename", *configFlag), + ).Error("Failed to open config file") os.Exit(2) } c, err := LoadConfig(cf) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "filename": configFlag, - }).Error("Failed to parse config file") + logger.With( + zap.Error(err), + zap.String("filename", *configFlag), + ).Error("Failed to parse config file") os.Exit(2) } a, err := c.Algorithm() if err != nil { - logger.WithFields(log.Fields{ - "error": err, - "algorithm": c.Name, - }).Error("Failed to get the algorithm") + logger.With( + zap.Error(err), + zap.String("algorithm", c.Name), + ).Error("Failed to get the algorithm") os.Exit(2) } inHeader, err := r.Read() if err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to read CSV header row") + logger.With( + zap.Error(err), + ).Error("Failed to read CSV header row") os.Exit(2) } // Generate and output the CSV header row outHeader, err := makeOutHeader(inHeader, generateColumnName()) if err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to generate output header row") + logger.With( + zap.Error(err), + ).Error("Failed to generate output header row") os.Exit(2) } if err := w.Write(outHeader); err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to write CSV header row") + logger.With( + zap.Error(err), + ).Error("Failed to write CSV header row") os.Exit(2) } @@ -222,9 +229,9 @@ func main() { break } if err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to read CSV row") + logger.With( + zap.Error(err), + ).Error("Failed to read CSV row") os.Exit(2) } record := makeRecord(inHeader, row) @@ -237,9 +244,9 @@ func main() { t := pq.Len() for i := 0; i < t; i++ { if err := w.Write(pq.PopRow()); err != nil { - logger.WithFields(log.Fields{ - "error": err, - }).Error("Failed to write CSV header row") + logger.With( + zap.Error(err), + ).Error("Failed to write CSV header row") os.Exit(2) } } diff --git a/go.mod b/go.mod index c8c57415..dc14ab40 100644 --- a/go.mod +++ b/go.mod @@ -11,7 +11,6 @@ require ( github.com/iancoleman/strcase v0.2.0 github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 - github.com/sirupsen/logrus v1.8.1 go.uber.org/zap v1.23.0 gocloud.dev v0.26.0 google.golang.org/api v0.88.0 @@ -41,6 +40,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect github.com/aws/smithy-go v1.11.2 // indirect + github.com/benbjohnson/clock v1.1.0 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect github.com/go-logr/logr v1.2.3 // indirect @@ -55,6 +55,7 @@ require ( github.com/googleapis/gax-go/v2 v2.4.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect + github.com/sirupsen/logrus v1.8.1 // indirect go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect diff --git a/internal/textvarflag/flag_test.go b/internal/textvarflag/flag_test.go index 2f20fff9..74862f0f 100644 --- a/internal/textvarflag/flag_test.go +++ b/internal/textvarflag/flag_test.go @@ -19,8 +19,6 @@ import ( "net" "testing" - "github.com/sirupsen/logrus" - "github.com/ossf/criticality_score/internal/textvarflag" ) @@ -48,7 +46,7 @@ func TestFlagSet(t *testing.T) { t.Fatalf("Parse() == %v, want nil", err) } if expect := net.IPv4(127, 0, 0, 1); !expect.Equal(ip) { - t.Fatalf("ip == %v, want %v", ip, logrus.FatalLevel) + t.Fatalf("ip == %v, want %v", ip, expect) } } From b9199a2dd20b566d7e874a39bc4967cddf574eca Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 28 Sep 2022 15:07:45 +1000 Subject: [PATCH 104/172] Update CONTRIBUTING guide to point to Go code. (#206) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- CONTRIBUTING.md | 57 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 44 insertions(+), 13 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7b8256af..4e9a89e3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,9 +1,10 @@ # Contributing to OSS Criticality Score! -Thank you for contributing your time and expertise to the OSS Criticality Score project. -This document describes the contribution guidelines for the project. +Thank you for contributing your time and expertise to the OSS Criticality Score +project. This document describes the contribution guidelines for the project. -**Note:** Before you start contributing, you must read and abide by our **[Code of Conduct](./CODE_OF_CONDUCT.md)**. +**Note:** Before you start contributing, you must read and abide by our +**[Code of Conduct](./CODE_OF_CONDUCT.md)**. ## Contributing code @@ -11,33 +12,63 @@ This document describes the contribution guidelines for the project. 1. Create [a GitHub account](https://github.com/join) 1. Create a [personal access token](https://docs.github.com/en/free-pro-team@latest/developers/apps/about-apps#personal-access-tokens) +1. (Optionally) a Google Cloud Platform account for [deps.dev](https://deps.dev) data 1. Set up your [development environment](#environment-setup) Then you can [iterate](#iterating). - -### Environment Setup + +## Environment Setup You must install these tools: 1. [`git`](https://help.github.com/articles/set-up-git/): For source control. -1. [`python`](https://www.python.org/downloads/): For running code. - -1. [`python-gitlab`](https://pypi.org/project/python-gitlab/) and [`PyGithub`](https://pypi.org/project/PyGithub/) pip packages. +1. [`go`](https://go.dev/dl/): For running code. + +And optionally: + +1. [`gcloud`](https://cloud.google.com/sdk/docs/install): For Google Cloud Platform access for deps.dev data. + +Then clone the repository, e.g: ```shell -pip3 install python-gitlab PyGithub +$ git clone git@github.com:ossf/criticality_score.git +$ cd criticality_score ``` ## Iterating -1. Make any code changes to the criticality score algorithm -[here](https://github.com/ossf/criticality_score/tree/main/criticality_score). +1. Find or create an [issue](https://github.com/ossf/criticality_score/issues) -1. Run the criticality score code using: +1. Make code changes to: + - the [GitHub enumerator](https://github.com/ossf/criticality_score/tree/main/cmd/enumerate_github) + - the [signal collector](https://github.com/ossf/criticality_score/tree/main/cmd/collect_signals) + - the [scorer](https://github.com/ossf/criticality_score/tree/main/cmd/scorer) + - the scorer [algorithm configuration](https://github.com/ossf/criticality_score/tree/main/config/scorer) + +1. Run your changes. For example, for a single repository this can be done by + executing: ```shell -python3 -m criticality_score.run --repo= +$ export GITHUB_TOKEN=ghp_x # the personal access token created above +$ echo "https://github.com/{ a repo }" | \ + go run ./cmd/collect_signals \ + -log=debug \ + -depsdev-disable \ # remove if you have a GCP account configured + - - | \ + go run ./cmd/scorer \ + -log=debug \ + -config=config/scorer/original_pike.yml \ + - - ``` +Note: Each of the tools listed above can be run individually and has their own +README. + +4. Ensure your code passes tests and lint checks: +```shell +$ make test +$ make lint +``` +5. Commit your change. Upload to a fork, and create a pull request! \ No newline at end of file From 136c34b9994a4cf0b6f81a1e6c5ff6c1bb054094 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 30 Sep 2022 13:18:26 +1000 Subject: [PATCH 105/172] Upgrade to Go 1.19 (#208) * Bump go version 1.19 Signed-off-by: Caleb Brown * Update the Go base image to 1.19.1 linux/amd64 Signed-off-by: Caleb Brown * Migrate to flag.TextVar in Go 1.19 Signed-off-by: Caleb Brown * Remove backport of textvarflag because we are now on Go 1.19. Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- .github/workflows/ci.yml | 4 +- cmd/collect_signals/main.go | 3 +- cmd/enumerate_github/Dockerfile | 2 +- cmd/enumerate_github/main.go | 5 +- cmd/scorer/main.go | 3 +- go.mod | 2 +- internal/textvarflag/flag.go | 92 ------------------------------- internal/textvarflag/flag_test.go | 61 -------------------- 8 files changed, 8 insertions(+), 164 deletions(-) delete mode 100644 internal/textvarflag/flag.go delete mode 100644 internal/textvarflag/flag_test.go diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14dadd5a..a5e14dc3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f with: - go-version: 1.18 + go-version: 1.19 - name: Run tests run: make test run-linter: @@ -24,6 +24,6 @@ jobs: - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f with: - go-version: 1.18 + go-version: 1.19 - name: golangci-lint uses: golangci/golangci-lint-action@537aa1903e5d359d0b27dbc19ddd22c5087f3fbc diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index ccfb6944..b1e44925 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -41,7 +41,6 @@ import ( "github.com/ossf/criticality_score/internal/githubapi" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" - "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" ) @@ -58,7 +57,7 @@ var ( func init() { flag.Var(&logLevel, "log", "set the `level` of logging.") - textvarflag.TextVar(flag.CommandLine, &logEnv, "log-env", log.DefaultEnv, "set logging `env`.") + flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) diff --git a/cmd/enumerate_github/Dockerfile b/cmd/enumerate_github/Dockerfile index 0bbeda4f..4d6aa37f 100644 --- a/cmd/enumerate_github/Dockerfile +++ b/cmd/enumerate_github/Dockerfile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM golang@sha256:684d791f8fd1b28485ee32239d92cde7099d97c88c5ed2e955f65f4adcf35d0f AS base +FROM golang@sha256:122f3484f844467ebe0674cf57272e61981770eb0bc7d316d1f0be281a88229f AS base WORKDIR /src ENV CGO_ENABLED=0 COPY go.mod go.sum ./ diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 9d820b3f..9db6d24f 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -37,7 +37,6 @@ import ( "github.com/ossf/criticality_score/internal/envflag" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" - "github.com/ossf/criticality_score/internal/textvarflag" "github.com/ossf/criticality_score/internal/workerpool" ) @@ -106,8 +105,8 @@ func init() { flag.Var(&startDateFlag, "start", "the start `date` to enumerate back to. Must be at or after 2008-01-01.") flag.Var(&endDateFlag, "end", "the end `date` to enumerate from.") flag.Var(&logLevel, "log", "set the `level` of logging.") - textvarflag.TextVar(flag.CommandLine, &format, "format", repowriter.WriterTypeText, "set output file `format`.") - textvarflag.TextVar(flag.CommandLine, &logEnv, "log-env", log.DefaultEnv, "set logging `env`.") + flag.TextVar(&format, "format", repowriter.WriterTypeText, "set output file `format`.") + flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") outfile.DefineFlags(flag.CommandLine, "force", "append", "FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index f8dd7726..f714bca9 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -51,7 +51,6 @@ import ( _ "github.com/ossf/criticality_score/cmd/scorer/algorithm/wam" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" - "github.com/ossf/criticality_score/internal/textvarflag" ) const defaultLogLevel = zapcore.InfoLevel @@ -65,7 +64,7 @@ var ( func init() { flag.Var(&logLevel, "log", "set the `level` of logging.") - textvarflag.TextVar(flag.CommandLine, &logEnv, "log-env", log.DefaultEnv, "set logging `env`.") + flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") // TODO: add the ability to disable "append" flag.Usage = func() { cmdName := path.Base(os.Args[0]) diff --git a/go.mod b/go.mod index dc14ab40..409c9765 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/ossf/criticality_score -go 1.18 +go 1.19 require ( cloud.google.com/go/bigquery v1.32.0 diff --git a/internal/textvarflag/flag.go b/internal/textvarflag/flag.go deleted file mode 100644 index a9f77e11..00000000 --- a/internal/textvarflag/flag.go +++ /dev/null @@ -1,92 +0,0 @@ -/* -Copyright (c) 2009 The Go Authors. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: - - * Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. - * Neither the name of Google Inc. nor the names of its -contributors may be used to endorse or promote products derived from -this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -/* -Package textvarflag is a backport of flag.TextVar from Go 1.19. - -Source: https://cs.opensource.google/go/go/+/master:src/flag/flag.go. - -Once Go 1.19 has been released this package can be removed. -*/ -package textvarflag - -import ( - "encoding" - "flag" - "fmt" - "reflect" -) - -// -- encoding.TextUnmarshaler Value -type textValue struct{ p encoding.TextUnmarshaler } - -func newTextValue(val encoding.TextMarshaler, p encoding.TextUnmarshaler) textValue { - ptrVal := reflect.ValueOf(p) - if ptrVal.Kind() != reflect.Ptr { - panic("variable value type must be a pointer") - } - defVal := reflect.ValueOf(val) - if defVal.Kind() == reflect.Ptr { - defVal = defVal.Elem() - } - if defVal.Type() != ptrVal.Type().Elem() { - panic(fmt.Sprintf("default type does not match variable type: %v != %v", defVal.Type(), ptrVal.Type().Elem())) - } - ptrVal.Elem().Set(defVal) - return textValue{p} -} - -func (v textValue) Set(s string) error { - return v.p.UnmarshalText([]byte(s)) -} - -func (v textValue) Get() interface{} { - return v.p -} - -func (v textValue) String() string { - if m, ok := v.p.(encoding.TextMarshaler); ok { - if b, err := m.MarshalText(); err == nil { - return string(b) - } - } - return "" -} - -// TextVar defines a flag with a specified name, default value, and usage string. -// The argument p must be a pointer to a variable that will hold the value -// of the flag, and p must implement encoding.TextUnmarshaler. -// If the flag is used, the flag value will be passed to p's UnmarshalText method. -// The type of the default value must be the same as the type of p. -// -// TextVar is a backport of the 1.19 implementation of flag.TextVar. -func TextVar(fs *flag.FlagSet, p encoding.TextUnmarshaler, name string, value encoding.TextMarshaler, usage string) { - fs.Var(newTextValue(value, p), name, usage) -} diff --git a/internal/textvarflag/flag_test.go b/internal/textvarflag/flag_test.go deleted file mode 100644 index 74862f0f..00000000 --- a/internal/textvarflag/flag_test.go +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2022 Criticality Score 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 -// -// 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. - -package textvarflag_test - -import ( - "flag" - "net" - "testing" - - "github.com/ossf/criticality_score/internal/textvarflag" -) - -var defaultIP = net.IPv4(192, 168, 0, 100) - -func TestFlagUnset(t *testing.T) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - var ip net.IP - textvarflag.TextVar(fs, &ip, "ip", defaultIP, "usage") - err := fs.Parse([]string{"arg"}) - if err != nil { - t.Fatalf("Parse() == %v, want nil", err) - } - if !defaultIP.Equal(ip) { - t.Fatalf("ip == %v, want %v", ip, defaultIP) - } -} - -func TestFlagSet(t *testing.T) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - var ip net.IP - textvarflag.TextVar(fs, &ip, "ip", defaultIP, "usage") - err := fs.Parse([]string{"-ip=127.0.0.1", "arg"}) - if err != nil { - t.Fatalf("Parse() == %v, want nil", err) - } - if expect := net.IPv4(127, 0, 0, 1); !expect.Equal(ip) { - t.Fatalf("ip == %v, want %v", ip, expect) - } -} - -func TestFlagSetError(t *testing.T) { - fs := flag.NewFlagSet("", flag.ContinueOnError) - var ip net.IP - textvarflag.TextVar(fs, &ip, "ip", defaultIP, "usage") - err := fs.Parse([]string{"-ip=256.0.0.1", "arg"}) - if err == nil { - t.Fatalf("Parse() == nil, want an error") - } -} From a267494b3d4604ee5997fa82c835d2a72d346f0f Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 4 Oct 2022 12:14:24 +1100 Subject: [PATCH 106/172] Complete the GitHub enumeration roll-out. (#210) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- infra/k8s/enumerate_github.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml index b51f4cbd..9784b255 100644 --- a/infra/k8s/enumerate_github.yaml +++ b/infra/k8s/enumerate_github.yaml @@ -17,8 +17,8 @@ kind: CronJob metadata: name: criticality-score-enumerate-github spec: - # Initially, run this daily at 23:00UTC for >=100 stars across 2021. - schedule: "0 23 * * *" + # Run twice weekly, on Sunday and Wednesday, at 23:00UTC for >=20 stars. + schedule: "0 23 * * 0,3" concurrencyPolicy: "Forbid" jobTemplate: spec: @@ -27,7 +27,7 @@ spec: containers: - name: enumerate-github image: gcr.io/openssf/criticality-score-enumerate-github:latest - args: ["gs://ossf-criticality-score-url-data/[[runid]]/github.txt"] + args: ["gs://ossf-criticality-score-url-data/[[runid]]/github.csv"] imagePullPolicy: Always env: - name: GITHUB_AUTH_SERVER @@ -37,11 +37,11 @@ spec: - name: CRITICALITY_SCORE_OUTFILE_FORCE value: "1" - name: CRITICALITY_SCORE_STARS_MIN - value: "50" + value: "20" - name: CRITICALITY_SCORE_START_DATE - value: "2021-01-01" - - name: CRITICALITY_SCORE_END_DATE - value: "2022-01-01" + value: "2008-01-01" + - name: CRITICALITY_SCORE_FORMAT + value: "scorecard" resources: limits: memory: 5Gi From a7feb0672ef3c66ca0715f347678447617ba8edb Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 4 Oct 2022 14:21:33 +1100 Subject: [PATCH 107/172] Add a SECURITY.md file. (#212) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- SECURITY.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 SECURITY.md diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 00000000..65b40899 --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,11 @@ +# Reporting Security Issues + +To report a security issue, please email +[oss-security@googlegroups.com](mailto:oss-security@googlegroups.com) +with a description of the issue, the steps you took to create the issue, +affected versions, and, if known, mitigations for the issue. + +Our vulnerability management team will respond within 3 working days of your +email. If the issue is confirmed as a vulnerability, we will open a +Security Advisory and acknowledge your contributions as part of it. This project +follows a 90 day disclosure timeline. From e62861ebb1db97e958d18ec919d48df561bd2d12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 7 Oct 2022 12:08:48 +1100 Subject: [PATCH 108/172] Bump actions/checkout from 3 to 3.1.0 (#213) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 3.1.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/scorecards.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a5e14dc3..468369cf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: run-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f with: go-version: 1.19 @@ -21,7 +21,7 @@ jobs: run-linter: runs-on: ubuntu-latest steps: - - uses: actions/checkout@a12a3943b4bdde767164f792f33f40b04645d846 + - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f with: go-version: 1.19 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index e188d16d..1f0fcc6f 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 830b51d1..cc2bd5ad 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -19,7 +19,7 @@ jobs: id-token: write steps: - name: "Checkout code" - uses: actions/checkout@2541b1294d2704b0964813337f33b291d3f8596b + uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: "Run analysis" uses: ossf/scorecard-action@865b4092859256271290c77adbd10a43f4779972 # v2.0.0-alpha.2 with: From 16ee912072581452bdde387aef9e0e5cb408ddf4 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 24 Oct 2022 10:31:38 +1100 Subject: [PATCH 109/172] Initial refactoring to support production workers (#214) Major refactoring to support production workers alongside CLI invocation. This also supports Python deprecation as well. Primary changes: * Renamed "Collector" interface to "Source". * Refactored most of `collect_signals` code into a "collector" package for running signal collection. * Generalised file input. * Bumped some versions Complete change summary: * Simplify the input to collect_signals to a single file. * Generalize the input file opening to help shrink the main() funcs. * Bump some dependency versions. * Bump golangci-lint version. * Use infile in scorer. * Move collector init into a separate function to make main() smaller. * Move file IO slightly. * Rename the "Collector" interface to "Source". * Move the Source interface into signal, and rename other files to reflect * Update the milestone 1 doc to reflect the code changes. * Relocate signal and projectrepo under internal/collector. * Move collector.Registry into the internal/collector package. * Move githubmentions to /internal/collector * Move depsdev to internal/collector * Move github to internal/collector/ * Fix typo Signed-off-by: Caleb Brown --- cmd/collect_signals/README.md | 6 +- cmd/collect_signals/main.go | 127 +++++++++--------- cmd/collect_signals/result/csv.go | 2 +- cmd/collect_signals/result/emitter.go | 2 +- cmd/scorer/main.go | 29 ++-- docs/design/milestone_1.md | 46 +++---- go.mod | 4 +- go.sum | 7 +- go.work.sum | 11 +- .../collector}/depsdev/bq.go | 0 .../collector}/depsdev/dependents.go | 0 .../collector/depsdev/source.go | 19 ++- .../collector}/github/factory.go | 2 +- .../collector}/github/legacy/constants.go | 0 .../collector}/github/legacy/contributors.go | 2 +- .../collector}/github/legacy/created.go | 2 +- .../collector}/github/legacy/issues.go | 2 +- .../collector}/github/legacy/releases.go | 0 .../collector}/github/legacy/util.go | 0 .../collector}/github/queries.go | 0 .../collector}/github/repo.go | 2 +- .../collector/github/source.go | 22 +-- .../collector/githubmentions/source.go | 20 +-- .../collector}/projectrepo/repo.go | 0 .../collector}/projectrepo/resolver.go | 0 .../collector/registry.go | 78 +++++------ .../collector}/signal/issues.go | 0 .../collector}/signal/repo.go | 0 .../collector}/signal/signal.go | 0 .../collector/signal/source.go | 22 ++- internal/githubapi/client.go | 2 +- internal/githubapi/errors.go | 2 +- internal/githubapi/roundtripper.go | 2 +- internal/infile/infile.go | 29 ++++ internal/infile/infile_test.go | 55 ++++++++ internal/outfile/outfile.go | 26 +--- internal/outfile/outfile_test.go | 4 +- tools/go.mod | 53 ++++---- tools/go.sum | 121 ++++++++++------- 39 files changed, 389 insertions(+), 310 deletions(-) rename {cmd/collect_signals => internal/collector}/depsdev/bq.go (100%) rename {cmd/collect_signals => internal/collector}/depsdev/dependents.go (100%) rename cmd/collect_signals/depsdev/collector.go => internal/collector/depsdev/source.go (76%) rename {cmd/collect_signals => internal/collector}/github/factory.go (94%) rename {cmd/collect_signals => internal/collector}/github/legacy/constants.go (100%) rename {cmd/collect_signals => internal/collector}/github/legacy/contributors.go (98%) rename {cmd/collect_signals => internal/collector}/github/legacy/created.go (98%) rename {cmd/collect_signals => internal/collector}/github/legacy/issues.go (98%) rename {cmd/collect_signals => internal/collector}/github/legacy/releases.go (100%) rename {cmd/collect_signals => internal/collector}/github/legacy/util.go (100%) rename {cmd/collect_signals => internal/collector}/github/queries.go (100%) rename {cmd/collect_signals => internal/collector}/github/repo.go (96%) rename cmd/collect_signals/github/collector.go => internal/collector/github/source.go (85%) rename cmd/collect_signals/githubmentions/collector.go => internal/collector/githubmentions/source.go (75%) rename {cmd/collect_signals => internal/collector}/projectrepo/repo.go (100%) rename {cmd/collect_signals => internal/collector}/projectrepo/resolver.go (100%) rename {cmd/collect_signals => internal}/collector/registry.go (57%) rename {cmd/collect_signals => internal/collector}/signal/issues.go (100%) rename {cmd/collect_signals => internal/collector}/signal/repo.go (100%) rename {cmd/collect_signals => internal/collector}/signal/signal.go (100%) rename cmd/collect_signals/collector/collector.go => internal/collector/signal/source.go (55%) create mode 100644 internal/infile/infile.go create mode 100644 internal/infile/infile_test.go diff --git a/cmd/collect_signals/README.md b/cmd/collect_signals/README.md index c6377775..fca33115 100644 --- a/cmd/collect_signals/README.md +++ b/cmd/collect_signals/README.md @@ -28,11 +28,11 @@ $ go install github.com/ossf/criticality_score/cmd/collect_signals ## Usage ```shell -$ collect_signals [FLAGS]... IN_FILE... OUT_FILE +$ collect_signals [FLAGS]... IN_FILE OUT_FILE ``` -Project repository URLs are read from each `IN_FILE` specified. If `-` is passed -in as an `IN_FILE` URLs will read from STDIN, along with any other files specified. +Project repository URLs are read from the specified `IN_FILE`. If `-` is passed +in as an `IN_FILE` URLs will read from STDIN. Results are written in CSV format to `OUT_FILE`. If `OUT_FILE` is `-` the results will be written to STDOUT. diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index b1e44925..b4302510 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -19,7 +19,6 @@ import ( "context" "flag" "fmt" - "io" "net/http" "net/url" "os" @@ -32,13 +31,14 @@ import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" - "github.com/ossf/criticality_score/cmd/collect_signals/collector" - "github.com/ossf/criticality_score/cmd/collect_signals/depsdev" - "github.com/ossf/criticality_score/cmd/collect_signals/github" - "github.com/ossf/criticality_score/cmd/collect_signals/githubmentions" - "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" "github.com/ossf/criticality_score/cmd/collect_signals/result" + "github.com/ossf/criticality_score/internal/collector" + "github.com/ossf/criticality_score/internal/collector/depsdev" + "github.com/ossf/criticality_score/internal/collector/github" + "github.com/ossf/criticality_score/internal/collector/githubmentions" + "github.com/ossf/criticality_score/internal/collector/projectrepo" "github.com/ossf/criticality_score/internal/githubapi" + "github.com/ossf/criticality_score/internal/infile" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/workerpool" @@ -62,7 +62,7 @@ func init() { flag.Usage = func() { cmdName := path.Base(os.Args[0]) w := flag.CommandLine.Output() - fmt.Fprintf(w, "Usage:\n %s [FLAGS]... IN_FILE... OUT_FILE\n\n", cmdName) + fmt.Fprintf(w, "Usage:\n %s [FLAGS]... IN_FILE OUT_FILE\n\n", cmdName) fmt.Fprintf(w, "Collects signals for each project repository listed.\n") fmt.Fprintf(w, "IN_FILE must be either a file or - to read from stdin.\n") fmt.Fprintf(w, "OUT_FILE must be either be a file or - to write to stdout.\n") @@ -110,6 +110,26 @@ func handleRepo(ctx context.Context, logger *zap.Logger, u *url.URL, out result. } } +func initSources(ctx context.Context, logger *zap.Logger, ghClient *githubapi.Client) error { + collector.Register(&github.RepoSource{}) + collector.Register(&github.IssuesSource{}) + collector.Register(githubmentions.NewSource(ghClient)) + + if *depsdevDisableFlag { + // deps.dev collection source has been disabled, so skip it. + logger.Warn("deps.dev signal source is disabled.") + } else { + ddsource, err := depsdev.NewSource(ctx, logger, *gcpProjectFlag, *depsdevDatasetFlag) + if err != nil { + return fmt.Errorf("init deps.dev source: %w", err) + } + logger.Info("deps.dev signal source enabled") + collector.Register(ddsource) + } + + return nil +} + func main() { flag.Parse() @@ -123,50 +143,11 @@ func main() { innerLogger := zapr.NewLogger(logger) scLogger := &sclog.Logger{Logger: &innerLogger} - if flag.NArg() < 2 { - logger.Error("Must have at least one input file and an output file specified.") - os.Exit(2) - } - lastArg := flag.NArg() - 1 - - // Open all the in-files for reading - var readers []io.Reader - consumingStdin := false - for _, inFilename := range flag.Args()[:lastArg] { - if inFilename == "-" && !consumingStdin { - logger.Info("Reading from stdin") - // Only add stdin once. - consumingStdin = true - readers = append(readers, os.Stdin) - continue - } - logger.With( - zap.String("filename", inFilename), - ).Debug("Reading from file") - f, err := os.Open(inFilename) - if err != nil { - logger.With( - zap.String("filename", inFilename), - zap.Error(err), - ).Error("Failed to open an input file") - os.Exit(2) - } - defer f.Close() - readers = append(readers, f) - } - r := io.MultiReader(readers...) - - // Open the out-file for writing - outFilename := flag.Args()[lastArg] - w, err := outfile.Open(context.Background(), outFilename) - if err != nil { - logger.With( - zap.String("filename", outFilename), - zap.Error(err), - ).Error("Failed to open file for output") + // Complete the validation of args + if flag.NArg() != 2 { + logger.Error("Must have one input file and one output file specified.") os.Exit(2) } - defer w.Close() ctx := context.Background() @@ -183,25 +164,39 @@ func main() { // Register all the Repo factories. projectrepo.Register(github.NewRepoFactory(ghClient, logger)) - // Register all the collectors that are supported. - collector.Register(&github.RepoCollector{}) - collector.Register(&github.IssuesCollector{}) - collector.Register(githubmentions.NewCollector(ghClient)) + // Register all the sources that are supported. + err = initSources(ctx, logger, ghClient) + if err != nil { + logger.With( + zap.Error(err), + ).Error("Failed to initialize sources") + os.Exit(2) + } - if *depsdevDisableFlag { - // deps.dev collection has been disabled, so skip it. - logger.Warn("deps.dev signal collection is disabled.") - } else { - ddcollector, err := depsdev.NewCollector(ctx, logger, *gcpProjectFlag, *depsdevDatasetFlag) - if err != nil { - logger.With( - zap.Error(err), - ).Error("Failed to create deps.dev collector") - os.Exit(2) - } - logger.Info("deps.dev signal collector enabled") - collector.Register(ddcollector) + inFilename := flag.Args()[0] + outFilename := flag.Args()[1] + + // Open the in-file for reading + r, err := infile.Open(context.Background(), inFilename) + if err != nil { + logger.With( + zap.String("filename", inFilename), + zap.Error(err), + ).Error("Failed to open an input file") + os.Exit(2) + } + defer r.Close() + + // Open the out-file for writing + w, err := outfile.Open(context.Background(), outFilename) + if err != nil { + logger.With( + zap.String("filename", outFilename), + zap.Error(err), + ).Error("Failed to open file for output") + os.Exit(2) } + defer w.Close() // Prepare the output writer out := result.NewCsvWriter(w, collector.EmptySets()) diff --git a/cmd/collect_signals/result/csv.go b/cmd/collect_signals/result/csv.go index 85faed30..03d8d49d 100644 --- a/cmd/collect_signals/result/csv.go +++ b/cmd/collect_signals/result/csv.go @@ -21,7 +21,7 @@ import ( "sync" "time" - "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/collector/signal" ) type csvWriter struct { diff --git a/cmd/collect_signals/result/emitter.go b/cmd/collect_signals/result/emitter.go index ccec56ce..a39d77bf 100644 --- a/cmd/collect_signals/result/emitter.go +++ b/cmd/collect_signals/result/emitter.go @@ -17,7 +17,7 @@ package result import ( "errors" - "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/collector/signal" ) var ErrorMarshalFailure = errors.New("failed to marshal value") diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index f714bca9..13882379 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -49,6 +49,7 @@ import ( "go.uber.org/zap/zapcore" _ "github.com/ossf/criticality_score/cmd/scorer/algorithm/wam" + "github.com/ossf/criticality_score/internal/infile" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" ) @@ -135,27 +136,19 @@ func main() { // Open the in-file for reading var r *csv.Reader - if inFilename == "-" { - logger.Info("Reading from stdin") - r = csv.NewReader(os.Stdin) - } else { + fr, err := infile.Open(context.Background(), inFilename) + if err != nil { logger.With( + zap.Error(err), zap.String("filename", inFilename), - ).Debug("Reading from file") - f, err := os.Open(inFilename) - if err != nil { - logger.With( - zap.Error(err), - zap.String("filename", inFilename), - ).Error("Failed to open input file") - os.Exit(2) - } - defer f.Close() - r = csv.NewReader(f) + ).Error("Failed to open input file") + os.Exit(2) } + defer fr.Close() + r = csv.NewReader(fr) // Open the out-file for writing - f, err := outfile.Open(context.Background(), outFilename) + fw, err := outfile.Open(context.Background(), outFilename) if err != nil { logger.With( zap.Error(err), @@ -163,8 +156,8 @@ func main() { ).Error("Failed to open file for output") os.Exit(2) } - defer f.Close() - w := csv.NewWriter(f) + defer fw.Close() + w := csv.NewWriter(fw) defer w.Flush() // Prepare the algorithm from the config file diff --git a/docs/design/milestone_1.md b/docs/design/milestone_1.md index 7ea6f807..7489a966 100644 --- a/docs/design/milestone_1.md +++ b/docs/design/milestone_1.md @@ -216,26 +216,26 @@ Output: * Either JSON or CSV formatted records for each project in UTF-8, including the project url. The output will support direct loading into BigQuery. -#### Signal Collectors +#### Signal Sources -Signal collection will be built around multiple signal _collectors_ that -produce one or more _signals_ per repository. +Signal collection will be built around multiple signal _sources_ that fetch +one or more _signals_ per repository from an individual source of data. -Signal collectors fall into one of three categories: +Signal sources fall into one of three categories: -* Source repository and hosting signal collectors (e.g. GitHub, Bitbucket, +* Source repository and hosting signal sources (e.g. GitHub, Bitbucket, cGit) -* Issue tracking signal collectors (e.g. GitHub, Bugzilla, JIRA) -* Additional signal collectors (e.g deps.dev) +* Issue tracking signal sources (e.g. GitHub, Bugzilla, JIRA) +* Additional signal sources (e.g deps.dev) -Each repository can have only one set of signals from a source repository -collector and one set of signals from an issue tracking signal collector, but -can have signals from many additional collectors. +Each repository can have only one set of signals from a repository signal +source and one set of signals from an issue tracking signal source, but +can have signals from many additional sources. #### Repository Object During the collection process a repository object will be created and passed to -each collector. +each source. As each part of the collection process runs, data will be fetched for a repository. The repository object will serve as the interface for accessing @@ -246,7 +246,7 @@ additional queries that need to be executed. The general process for collecting signals will do the following: -* Initialize all the collectors +* Initialize all the sources * For each repository URL * Gather basic data about the repository (e.g. stars, has it moved, urls) * It may have been removed, in which case the repository can be @@ -254,10 +254,10 @@ The general process for collecting signals will do the following: * It may not be "interesting" (e.g. too few stars) and should be skipped. * It may have already been processed and should be skipped. - * Determine the set of collectors that apply to the repository. - * For each collector: - * Start collecting the signals for the current repository - * Wait for all collectors to complete + * Determine the set of sources that apply to the repository. + * For each source: + * Start fetching the signals for the current repository + * Wait for all sources to complete * Write the signals to the output. #### Signal Fields @@ -265,22 +265,22 @@ The general process for collecting signals will do the following: ##### Naming Signal fields will fall under the general naming pattern of -`[collector].[name]`. +`[namespace].[name]`. -Where `[collector]` and `[name]` are made up of one or more of the +Where `[namespace]` and `[name]` are made up of one or more of the following: * Lowercase characters * Numbers * Underscores -The following restrictions further apply to `[collector]` names: +The following restrictions further apply to `[namespace]` names: -* Source repository signal collectors must use the `repo` collector name -* Issue tracking signal collectors must use the `issues` collector name +* Source repository signal sources must use the `repo` namespace +* Issue tracking signal sources must use the `issues` namespace * Signals matching the original set in the Python implementation can also use - the `legacy` collector name -* Additional collectors can use any other valid name. + the `legacy` namespace +* Additional sources can use any other valid namespace. Finally, `[name]` names must include the unit value if it is not implied by the type, and any time constraints. diff --git a/go.mod b/go.mod index 409c9765..9591da9c 100644 --- a/go.mod +++ b/go.mod @@ -6,8 +6,8 @@ require ( cloud.google.com/go/bigquery v1.32.0 github.com/blendle/zapdriver v1.3.1 github.com/go-logr/zapr v1.2.3 - github.com/google/go-cmp v0.5.8 - github.com/google/go-github/v44 v44.1.0 + github.com/google/go-cmp v0.5.9 + github.com/google/go-github/v47 v47.1.0 github.com/iancoleman/strcase v0.2.0 github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 diff --git a/go.sum b/go.sum index a93f6b88..6a9949e3 100644 --- a/go.sum +++ b/go.sum @@ -296,12 +296,13 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= -github.com/google/go-github/v44 v44.1.0 h1:shWPaufgdhr+Ad4eo/pZv9ORTxFpsxPEPEuuXAKIQGA= -github.com/google/go-github/v44 v44.1.0/go.mod h1:iWn00mWcP6PRWHhXm0zuFJ8wbEjE5AGO5D5HXYM4zgw= +github.com/google/go-github/v47 v47.1.0 h1:Cacm/WxQBOa9lF0FT0EMjZ2BWMetQ1TQfyurn4yF1z8= +github.com/google/go-github/v47 v47.1.0/go.mod h1:VPZBXNbFSJGjyjFRUKo9vZGawTajnWzC/YjGw/oFKi0= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE= diff --git a/go.work.sum b/go.work.sum index 63323c46..9dafb0b3 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,18 +1,19 @@ -github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/Abirdcfly/dupword v0.0.7 h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kkHAIKE/contextcheck v1.1.2 h1:BYUSG/GhMhqVz//yjl8IkBDlMEws+9DtCmkz18QO1gg= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= +github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc= google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= diff --git a/cmd/collect_signals/depsdev/bq.go b/internal/collector/depsdev/bq.go similarity index 100% rename from cmd/collect_signals/depsdev/bq.go rename to internal/collector/depsdev/bq.go diff --git a/cmd/collect_signals/depsdev/dependents.go b/internal/collector/depsdev/dependents.go similarity index 100% rename from cmd/collect_signals/depsdev/dependents.go rename to internal/collector/depsdev/dependents.go diff --git a/cmd/collect_signals/depsdev/collector.go b/internal/collector/depsdev/source.go similarity index 76% rename from cmd/collect_signals/depsdev/collector.go rename to internal/collector/depsdev/source.go index f0d9b876..71779076 100644 --- a/cmd/collect_signals/depsdev/collector.go +++ b/internal/collector/depsdev/source.go @@ -22,9 +22,8 @@ import ( "cloud.google.com/go/bigquery" "go.uber.org/zap" - "github.com/ossf/criticality_score/cmd/collect_signals/collector" - "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" - "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/collector/projectrepo" + "github.com/ossf/criticality_score/internal/collector/signal" ) const ( @@ -40,21 +39,21 @@ func (s *depsDevSet) Namespace() signal.Namespace { return signal.Namespace("depsdev") } -type depsDevCollector struct { +type depsDevSource struct { logger *zap.Logger dependents *dependents } -func (c *depsDevCollector) EmptySet() signal.Set { +func (c *depsDevSource) EmptySet() signal.Set { return &depsDevSet{} } -func (c *depsDevCollector) IsSupported(r projectrepo.Repo) bool { +func (c *depsDevSource) IsSupported(r projectrepo.Repo) bool { _, t := parseRepoURL(r.URL()) return t != "" } -func (c *depsDevCollector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (c *depsDevSource) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { var s depsDevSet n, t := parseRepoURL(r.URL()) if t == "" { @@ -71,12 +70,12 @@ func (c *depsDevCollector) Collect(ctx context.Context, r projectrepo.Repo) (sig return &s, nil } -// NewCollector creates a new Collector for gathering data from deps.dev. +// NewSource creates a new Source for gathering data from deps.dev. // // TODO add options to configure the dataset: // - force dataset re-creation (-update-strategy = always,stale,weekly,monthly,never) // - force dataset destruction (-depsdev-destroy-data) -func NewCollector(ctx context.Context, logger *zap.Logger, projectID, datasetName string) (collector.Collector, error) { +func NewSource(ctx context.Context, logger *zap.Logger, projectID, datasetName string) (signal.Source, error) { if projectID == "" { projectID = bigquery.DetectProjectID } @@ -92,7 +91,7 @@ func NewCollector(ctx context.Context, logger *zap.Logger, projectID, datasetNam return nil, err } - return &depsDevCollector{ + return &depsDevSource{ logger: logger, dependents: dependents, }, nil diff --git a/cmd/collect_signals/github/factory.go b/internal/collector/github/factory.go similarity index 94% rename from cmd/collect_signals/github/factory.go rename to internal/collector/github/factory.go index cd8803a3..05a90ed3 100644 --- a/cmd/collect_signals/github/factory.go +++ b/internal/collector/github/factory.go @@ -20,7 +20,7 @@ import ( "go.uber.org/zap" - "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" + "github.com/ossf/criticality_score/internal/collector/projectrepo" "github.com/ossf/criticality_score/internal/githubapi" ) diff --git a/cmd/collect_signals/github/legacy/constants.go b/internal/collector/github/legacy/constants.go similarity index 100% rename from cmd/collect_signals/github/legacy/constants.go rename to internal/collector/github/legacy/constants.go diff --git a/cmd/collect_signals/github/legacy/contributors.go b/internal/collector/github/legacy/contributors.go similarity index 98% rename from cmd/collect_signals/github/legacy/contributors.go rename to internal/collector/github/legacy/contributors.go index 2c634740..0e6d2098 100644 --- a/cmd/collect_signals/github/legacy/contributors.go +++ b/internal/collector/github/legacy/contributors.go @@ -20,7 +20,7 @@ import ( "fmt" "strings" - "github.com/google/go-github/v44/github" + "github.com/google/go-github/v47/github" "github.com/ossf/criticality_score/internal/githubapi" ) diff --git a/cmd/collect_signals/github/legacy/created.go b/internal/collector/github/legacy/created.go similarity index 98% rename from cmd/collect_signals/github/legacy/created.go rename to internal/collector/github/legacy/created.go index b2043854..0c808d52 100644 --- a/cmd/collect_signals/github/legacy/created.go +++ b/internal/collector/github/legacy/created.go @@ -19,7 +19,7 @@ import ( "fmt" "time" - "github.com/google/go-github/v44/github" + "github.com/google/go-github/v47/github" "github.com/ossf/criticality_score/internal/githubapi" ) diff --git a/cmd/collect_signals/github/legacy/issues.go b/internal/collector/github/legacy/issues.go similarity index 98% rename from cmd/collect_signals/github/legacy/issues.go rename to internal/collector/github/legacy/issues.go index 8dc1612c..e717ec5e 100644 --- a/cmd/collect_signals/github/legacy/issues.go +++ b/internal/collector/github/legacy/issues.go @@ -18,7 +18,7 @@ import ( "context" "time" - "github.com/google/go-github/v44/github" + "github.com/google/go-github/v47/github" "github.com/ossf/criticality_score/internal/githubapi" ) diff --git a/cmd/collect_signals/github/legacy/releases.go b/internal/collector/github/legacy/releases.go similarity index 100% rename from cmd/collect_signals/github/legacy/releases.go rename to internal/collector/github/legacy/releases.go diff --git a/cmd/collect_signals/github/legacy/util.go b/internal/collector/github/legacy/util.go similarity index 100% rename from cmd/collect_signals/github/legacy/util.go rename to internal/collector/github/legacy/util.go diff --git a/cmd/collect_signals/github/queries.go b/internal/collector/github/queries.go similarity index 100% rename from cmd/collect_signals/github/queries.go rename to internal/collector/github/queries.go diff --git a/cmd/collect_signals/github/repo.go b/internal/collector/github/repo.go similarity index 96% rename from cmd/collect_signals/github/repo.go rename to internal/collector/github/repo.go index 8bf11dc9..ce9f685e 100644 --- a/cmd/collect_signals/github/repo.go +++ b/internal/collector/github/repo.go @@ -21,7 +21,7 @@ import ( "go.uber.org/zap" - "github.com/ossf/criticality_score/cmd/collect_signals/github/legacy" + "github.com/ossf/criticality_score/internal/collector/github/legacy" "github.com/ossf/criticality_score/internal/githubapi" ) diff --git a/cmd/collect_signals/github/collector.go b/internal/collector/github/source.go similarity index 85% rename from cmd/collect_signals/github/collector.go rename to internal/collector/github/source.go index 230e5341..acd8e7d3 100644 --- a/cmd/collect_signals/github/collector.go +++ b/internal/collector/github/source.go @@ -19,18 +19,18 @@ import ( "errors" "time" - "github.com/ossf/criticality_score/cmd/collect_signals/github/legacy" - "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" - "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/collector/github/legacy" + "github.com/ossf/criticality_score/internal/collector/projectrepo" + "github.com/ossf/criticality_score/internal/collector/signal" ) -type RepoCollector struct{} +type RepoSource struct{} -func (rc *RepoCollector) EmptySet() signal.Set { +func (rc *RepoSource) EmptySet() signal.Set { return &signal.RepoSet{} } -func (rc *RepoCollector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (rc *RepoSource) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { ghr, ok := r.(*repo) if !ok { return nil, errors.New("project is not a github project") @@ -80,18 +80,18 @@ func (rc *RepoCollector) Collect(ctx context.Context, r projectrepo.Repo) (signa return s, nil } -func (rc *RepoCollector) IsSupported(p projectrepo.Repo) bool { +func (rc *RepoSource) IsSupported(p projectrepo.Repo) bool { _, ok := p.(*repo) return ok } -type IssuesCollector struct{} +type IssuesSource struct{} -func (ic *IssuesCollector) EmptySet() signal.Set { +func (ic *IssuesSource) EmptySet() signal.Set { return &signal.IssuesSet{} } -func (ic *IssuesCollector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (ic *IssuesSource) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { ghr, ok := r.(*repo) if !ok { return nil, errors.New("project is not a github project") @@ -135,7 +135,7 @@ func (ic *IssuesCollector) Collect(ctx context.Context, r projectrepo.Repo) (sig return s, nil } -func (ic *IssuesCollector) IsSupported(r projectrepo.Repo) bool { +func (ic *IssuesSource) IsSupported(r projectrepo.Repo) bool { _, ok := r.(*repo) return ok } diff --git a/cmd/collect_signals/githubmentions/collector.go b/internal/collector/githubmentions/source.go similarity index 75% rename from cmd/collect_signals/githubmentions/collector.go rename to internal/collector/githubmentions/source.go index ef955489..46e456ab 100644 --- a/cmd/collect_signals/githubmentions/collector.go +++ b/internal/collector/githubmentions/source.go @@ -26,10 +26,10 @@ import ( "net/url" "strings" - "github.com/google/go-github/v44/github" + "github.com/google/go-github/v47/github" - "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" - "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/collector/projectrepo" + "github.com/ossf/criticality_score/internal/collector/signal" "github.com/ossf/criticality_score/internal/githubapi" ) @@ -41,25 +41,25 @@ func (s *mentionSet) Namespace() signal.Namespace { return signal.Namespace("github_mentions") } -type Collector struct { +type Source struct { client *githubapi.Client } -func NewCollector(c *githubapi.Client) *Collector { - return &Collector{ +func NewSource(c *githubapi.Client) signal.Source { + return &Source{ client: c, } } -func (c *Collector) EmptySet() signal.Set { +func (c *Source) EmptySet() signal.Set { return &mentionSet{} } -func (c *Collector) IsSupported(r projectrepo.Repo) bool { +func (c *Source) IsSupported(r projectrepo.Repo) bool { return true } -func (c *Collector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (c *Source) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { s := &mentionSet{} if c, err := c.githubSearchTotalCommitMentions(ctx, r.URL()); err != nil { return nil, err @@ -69,7 +69,7 @@ func (c *Collector) Collect(ctx context.Context, r projectrepo.Repo) (signal.Set return s, nil } -func (c *Collector) githubSearchTotalCommitMentions(ctx context.Context, u *url.URL) (int, error) { +func (c *Source) githubSearchTotalCommitMentions(ctx context.Context, u *url.URL) (int, error) { repoName := strings.Trim(u.Path, "/") opts := &github.SearchOptions{ ListOptions: github.ListOptions{PerPage: 1}, diff --git a/cmd/collect_signals/projectrepo/repo.go b/internal/collector/projectrepo/repo.go similarity index 100% rename from cmd/collect_signals/projectrepo/repo.go rename to internal/collector/projectrepo/repo.go diff --git a/cmd/collect_signals/projectrepo/resolver.go b/internal/collector/projectrepo/resolver.go similarity index 100% rename from cmd/collect_signals/projectrepo/resolver.go rename to internal/collector/projectrepo/resolver.go diff --git a/cmd/collect_signals/collector/registry.go b/internal/collector/registry.go similarity index 57% rename from cmd/collect_signals/collector/registry.go rename to internal/collector/registry.go index e006fa67..02706d78 100644 --- a/cmd/collect_signals/collector/registry.go +++ b/internal/collector/registry.go @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +// Package collector defines a registry for using signal sources together. package collector import ( "context" "fmt" - "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" - "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/collector/projectrepo" + "github.com/ossf/criticality_score/internal/collector/signal" ) // empty is a convenience wrapper for the empty struct. @@ -28,7 +29,7 @@ type empty struct{} var globalRegistry = NewRegistry() type Registry struct { - cs []Collector + ss []signal.Source } // NewRegistry creates a new instance of Registry. @@ -36,66 +37,65 @@ func NewRegistry() *Registry { return &Registry{} } -// containsCollector returns true if c has already been registered. -func (r *Registry) containsCollector(c Collector) bool { - for _, regC := range r.cs { - if regC == c { +// containsSource returns true if c has already been registered. +func (r *Registry) containsSource(s signal.Source) bool { + for _, regS := range r.ss { + if regS == s { return true } } return false } -// Register adds the Collector c to the registry to be used when Collect is -// called. +// Register adds the Source s to the registry to be used when Collect is called. // -// This method may panic if the Collector's signal Set is not valid, or if the -// Collector has already been added. +// This method may panic if the Source's signal Set is not valid, or if the +// Source has already been added. // -// The order which Collectors are added is preserved. -func (r *Registry) Register(c Collector) { - validateCollector(c) - if r.containsCollector(c) { - panic(fmt.Sprintf("collector %s has already been registered", c.EmptySet().Namespace())) +// The order which Sources are added is preserved. +func (r *Registry) Register(s signal.Source) { + validateSource(s) + if r.containsSource(s) { + panic(fmt.Sprintf("source %s has already been registered", s.EmptySet().Namespace())) } - if err := signal.ValidateSet(c.EmptySet()); err != nil { + if err := signal.ValidateSet(s.EmptySet()); err != nil { panic(err) } - r.cs = append(r.cs, c) + r.ss = append(r.ss, s) } -func (r *Registry) collectorsForRepository(repo projectrepo.Repo) []Collector { +func (r *Registry) sourcesForRepository(repo projectrepo.Repo) []signal.Source { // Check for duplicates using a map to preserve the insertion order - // of the collectors. + // of the sources. exists := make(map[signal.Namespace]empty) - var res []Collector - for _, c := range r.cs { - if !c.IsSupported(repo) { + var res []signal.Source + for _, s := range r.ss { + if !s.IsSupported(repo) { continue } - if _, ok := exists[c.EmptySet().Namespace()]; ok { - // This key'd collector already exists for this repo. + if _, ok := exists[s.EmptySet().Namespace()]; ok { + // This key'd source already exists for this repo. panic("") } // Record that we have seen this key - exists[c.EmptySet().Namespace()] = empty{} - res = append(res, c) + exists[s.EmptySet().Namespace()] = empty{} + res = append(res, s) } return res } // EmptySets returns all the empty signal Sets for all the registered -// Collectors. +// Sources. // // This result can be used to determine all the signals that are defined. // // The order of each empty Set is the same as the order of registration. If two -// Collectors return a Set with the same Namespace, only the first Set will be +// Sources return a Set with the same Namespace, only the first Set will be // included. func (r *Registry) EmptySets() []signal.Set { exists := make(map[signal.Namespace]empty) var ss []signal.Set - for _, c := range r.cs { + for _, c := range r.ss { // skip existing namespaces if _, ok := exists[c.EmptySet().Namespace()]; ok { continue @@ -107,10 +107,10 @@ func (r *Registry) EmptySets() []signal.Set { // Collect will collect all the signals for the given repo. func (r *Registry) Collect(ctx context.Context, repo projectrepo.Repo) ([]signal.Set, error) { - cs := r.collectorsForRepository(repo) + cs := r.sourcesForRepository(repo) var ss []signal.Set for _, c := range cs { - s, err := c.Collect(ctx, repo) + s, err := c.Get(ctx, repo) if err != nil { return nil, err } @@ -119,15 +119,15 @@ func (r *Registry) Collect(ctx context.Context, repo projectrepo.Repo) ([]signal return ss, nil } -// Register registers the collector with the global registry for use during +// Register registers the source with the global registry for use during // calls to Collect(). // // See Registry.Register(). -func Register(c Collector) { - globalRegistry.Register(c) +func Register(s signal.Source) { + globalRegistry.Register(s) } -// EmptySet returns all the empty signal Sets for all the Collectors registered +// EmptySet returns all the empty signal Sets for all the Sources registered // with the global registry. // // See Registry.EmptySets(). @@ -135,7 +135,7 @@ func EmptySets() []signal.Set { return globalRegistry.EmptySets() } -// Collect collects all the signals for the given repo using the Collectors +// Collect collects all the signals for the given repo using the Sources // registered with the global registry. // // See Registry.Collect(). @@ -143,7 +143,7 @@ func Collect(ctx context.Context, r projectrepo.Repo) ([]signal.Set, error) { return globalRegistry.Collect(ctx, r) } -func validateCollector(c Collector) { - // TODO - ensure a collector with the same Namespace as another use +func validateSource(s signal.Source) { + // TODO - ensure a source with the same Namespace as another use // the same signal.Set } diff --git a/cmd/collect_signals/signal/issues.go b/internal/collector/signal/issues.go similarity index 100% rename from cmd/collect_signals/signal/issues.go rename to internal/collector/signal/issues.go diff --git a/cmd/collect_signals/signal/repo.go b/internal/collector/signal/repo.go similarity index 100% rename from cmd/collect_signals/signal/repo.go rename to internal/collector/signal/repo.go diff --git a/cmd/collect_signals/signal/signal.go b/internal/collector/signal/signal.go similarity index 100% rename from cmd/collect_signals/signal/signal.go rename to internal/collector/signal/signal.go diff --git a/cmd/collect_signals/collector/collector.go b/internal/collector/signal/source.go similarity index 55% rename from cmd/collect_signals/collector/collector.go rename to internal/collector/signal/source.go index c214b6f5..5a508764 100644 --- a/cmd/collect_signals/collector/collector.go +++ b/internal/collector/signal/source.go @@ -12,30 +12,26 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package collector defines the interface for signal collectors and a registry -// for using the collectors together. -package collector +package signal import ( "context" - "github.com/ossf/criticality_score/cmd/collect_signals/projectrepo" - "github.com/ossf/criticality_score/cmd/collect_signals/signal" + "github.com/ossf/criticality_score/internal/collector/projectrepo" ) -// A Collector is used to collect a set of signals for a given -// project repository. -type Collector interface { +// A Source is used to get a set of signals for a given project repository. +type Source interface { // EmptySet returns an empty instance of a signal Set that can be used for - // determining the namespace and signals supported by the Collector. - EmptySet() signal.Set + // determining the namespace and signals supported by the Source. + EmptySet() Set - // IsSupported returns true if the Collector supports the supplied Repo. + // IsSupported returns true if the Source supports the supplied Repo. IsSupported(projectrepo.Repo) bool - // Collect gathers and returns a Set of signals for the given project repo. + // Get gathers and returns a Set of signals for the given project repo. // // An error is returned if it is unable to successfully gather the signals, // or if the context is cancelled. - Collect(context.Context, projectrepo.Repo) (signal.Set, error) + Get(context.Context, projectrepo.Repo) (Set, error) } diff --git a/internal/githubapi/client.go b/internal/githubapi/client.go index 850fad05..a0bf3590 100644 --- a/internal/githubapi/client.go +++ b/internal/githubapi/client.go @@ -17,7 +17,7 @@ package githubapi import ( "net/http" - "github.com/google/go-github/v44/github" + "github.com/google/go-github/v47/github" "github.com/shurcooL/githubv4" ) diff --git a/internal/githubapi/errors.go b/internal/githubapi/errors.go index b1cf0460..595f6b41 100644 --- a/internal/githubapi/errors.go +++ b/internal/githubapi/errors.go @@ -17,7 +17,7 @@ package githubapi import ( "errors" - "github.com/google/go-github/v44/github" + "github.com/google/go-github/v47/github" ) // ErrorResponseStatusCode will unwrap a github.ErrorResponse and return the diff --git a/internal/githubapi/roundtripper.go b/internal/githubapi/roundtripper.go index 6d626f22..8a7497cf 100644 --- a/internal/githubapi/roundtripper.go +++ b/internal/githubapi/roundtripper.go @@ -24,7 +24,7 @@ import ( "strings" "time" - "github.com/google/go-github/v44/github" + "github.com/google/go-github/v47/github" "go.uber.org/zap" "github.com/ossf/criticality_score/internal/retry" diff --git a/internal/infile/infile.go b/internal/infile/infile.go new file mode 100644 index 00000000..705e3ecd --- /dev/null +++ b/internal/infile/infile.go @@ -0,0 +1,29 @@ +package infile + +import ( + "context" + "io" + "os" +) + +// fileOpenFunc makes it possible to mock os.Open() for testing. +type fileOpenFunc func(string) (*os.File, error) + +var ( + fileOpen fileOpenFunc = os.Open + + // The name that is used to represent stdin. + StdinName = "-" +) + +// Open opens and returns a file for input with the given filename. +// +// If filename is equal to o.StdoutName, os.Stdin will be used. +// If filename does not exist, an error will be returned. +// If filename does exist, the file will be opened and returned. +func Open(ctx context.Context, filename string) (io.ReadCloser, error) { + if StdinName != "" && filename == StdinName { + return os.Stdin, nil + } + return fileOpen(filename) +} diff --git a/internal/infile/infile_test.go b/internal/infile/infile_test.go new file mode 100644 index 00000000..0b3c170d --- /dev/null +++ b/internal/infile/infile_test.go @@ -0,0 +1,55 @@ +package infile + +import ( + "context" + "errors" + "os" + "testing" +) + +func TestOpenStdin(t *testing.T) { + origStdinName := StdinName + defer func() { StdinName = origStdinName }() + StdinName = "-stdin-" + f, err := Open(context.Background(), "-stdin-") + if err != nil { + t.Fatalf("Open() == %v, want nil", err) + } + if f != os.Stdin { + t.Fatal("Open() == not stdin, want stdin") + } +} + +func TestOpen(t *testing.T) { + want := "path/to/file" + got := "" + fileOpen = func(filename string) (*os.File, error) { + got = filename + return &os.File{}, nil + } + + f, err := Open(context.Background(), want) + if err != nil { + t.Fatalf("Open() == %v, want nil", err) + } + if f == nil { + t.Fatal("Open() == nil, want a file") + } + if got != want { + t.Fatalf("Open(%q) opened %q", want, got) + } +} + +func TestOpenError(t *testing.T) { + want := errors.New("test error") + fileOpen = func(filename string) (*os.File, error) { + return nil, want + } + _, err := Open(context.Background(), "path/to/file") + if err == nil { + t.Fatalf("Open() is nil, want %v", want) + } + if !errors.Is(err, want) { + t.Fatalf("Open() returned %v, want %v", err, want) + } +} diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index 3256c27b..2ee365dd 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -30,25 +30,11 @@ import ( _ "gocloud.dev/blob/s3blob" ) -// fileOpener wraps a method for opening files. -// -// This allows tests to fake the behavior of os.OpenFile() to avoid hitting -// the filesystem. -type fileOpener interface { - Open(string, int, os.FileMode) (*os.File, error) -} - -// fileOpenerFunc allows a function to implement the openFileWrapper interface. -// -// This is convenient for wrapping os.OpenFile(). -type fileOpenerFunc func(string, int, os.FileMode) (*os.File, error) - -func (f fileOpenerFunc) Open(filename string, flags int, perm os.FileMode) (*os.File, error) { - return f(filename, flags, perm) -} +// fileOpenFunc makes it possible to mock os.OpenFile() for testing. +type fileOpenFunc func(string, int, os.FileMode) (*os.File, error) type Opener struct { - fileOpener fileOpener + fileOpener fileOpenFunc StdoutName string forceFlag string force bool @@ -61,7 +47,7 @@ func CreateOpener(fs *flag.FlagSet, forceFlag, appendFlag, fileHelpName string) o := &Opener{ Perm: 0o666, StdoutName: "-", - fileOpener: fileOpenerFunc(os.OpenFile), + fileOpener: os.OpenFile, forceFlag: forceFlag, } fs.BoolVar(&(o.force), forceFlag, false, fmt.Sprintf("overwrites %s if it already exists and -%s is not set.", fileHelpName, appendFlag)) @@ -70,7 +56,7 @@ func CreateOpener(fs *flag.FlagSet, forceFlag, appendFlag, fileHelpName string) } func (o *Opener) openFile(filename string, extraFlags int) (io.WriteCloser, error) { - return o.fileOpener.Open(filename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|extraFlags, o.Perm) + return o.fileOpener(filename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|extraFlags, o.Perm) } func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, error) { @@ -133,6 +119,8 @@ func DefineFlags(fs *flag.FlagSet, forceFlag, appendFlag, fileHelpName string) { } // Open is a wrapper around Opener.Open for the default instance of Opener. +// +// Must only be called after DefineFlags. func Open(ctx context.Context, filename string) (io.WriteCloser, error) { return defaultOpener.Open(ctx, filename) } diff --git a/internal/outfile/outfile_test.go b/internal/outfile/outfile_test.go index f5e7b858..e37609f3 100644 --- a/internal/outfile/outfile_test.go +++ b/internal/outfile/outfile_test.go @@ -41,7 +41,7 @@ func newTestOpener() *testOpener { o.opener = CreateOpener(o.flag, "force", "append", "FILE") o.opener.Perm = 0o567 o.opener.StdoutName = "-stdout-" - o.opener.fileOpener = fileOpenerFunc(func(filename string, flags int, perm os.FileMode) (*os.File, error) { + o.opener.fileOpener = func(filename string, flags int, perm os.FileMode) (*os.File, error) { o.lastOpen = &openCall{ filename: filename, flags: flags, @@ -52,7 +52,7 @@ func newTestOpener() *testOpener { } else { return &os.File{}, nil } - }) + } return o } diff --git a/tools/go.mod b/tools/go.mod index 935fb74a..b1ac9956 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -2,15 +2,18 @@ module github.com/ossf/criticality_score/tools go 1.19 +require github.com/golangci/golangci-lint v1.50.0 + require ( 4d63.com/gochecknoglobals v0.1.0 // indirect + github.com/Abirdcfly/dupword v0.0.7 // indirect github.com/Antonboom/errname v0.1.7 // indirect github.com/Antonboom/nilnil v0.1.1 // indirect github.com/BurntSushi/toml v1.2.0 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect - github.com/OpenPeeDeeP/depguard v1.1.0 // indirect + github.com/OpenPeeDeeP/depguard v1.1.1 // indirect github.com/alexkohler/prealloc v1.0.0 // indirect github.com/alingse/asasalint v0.0.11 // indirect github.com/ashanbrown/forbidigo v1.3.0 // indirect @@ -25,8 +28,8 @@ require ( github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect - github.com/curioswitch/go-reassign v0.1.2 // indirect - github.com/daixiang0/gci v0.6.3 // indirect + github.com/curioswitch/go-reassign v0.2.0 // indirect + github.com/daixiang0/gci v0.8.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/esimonov/ifshort v1.0.4 // indirect @@ -36,10 +39,10 @@ require ( github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect - github.com/go-critic/go-critic v0.6.4 // indirect + github.com/go-critic/go-critic v0.6.5 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect - github.com/go-toolsmith/astcopy v1.0.1 // indirect - github.com/go-toolsmith/astequal v1.0.2 // indirect + github.com/go-toolsmith/astcopy v1.0.2 // indirect + github.com/go-toolsmith/astequal v1.0.3 // indirect github.com/go-toolsmith/astfmt v1.0.0 // indirect github.com/go-toolsmith/astp v1.0.0 // indirect github.com/go-toolsmith/strparse v1.0.0 // indirect @@ -51,14 +54,13 @@ require ( github.com/golangci/check v0.0.0-20180506172741-cfe4005ccda2 // indirect github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe // indirect - github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a // indirect - github.com/golangci/golangci-lint v1.49.0 // indirect + github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect github.com/golangci/misspell v0.3.5 // indirect github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect - github.com/google/go-cmp v0.5.8 // indirect + github.com/google/go-cmp v0.5.9 // indirect github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect @@ -76,6 +78,7 @@ require ( github.com/julz/importas v0.1.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect + github.com/kkHAIKE/contextcheck v1.1.2 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect github.com/kyoh86/exportloopref v0.1.8 // indirect @@ -84,6 +87,7 @@ require ( github.com/leonklingele/grouper v1.1.0 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect + github.com/maratori/testableexamples v1.0.0 // indirect github.com/maratori/testpackage v1.1.0 // indirect github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect @@ -91,34 +95,34 @@ require ( github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.2.3 // indirect + github.com/mgechev/revive v1.2.4 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moricho/tparallel v0.2.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.8.1 // indirect + github.com/nishanths/exhaustive v0.8.3 // indirect github.com/nishanths/predeclared v0.2.2 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect - github.com/pelletier/go-toml/v2 v2.0.2 // indirect + github.com/pelletier/go-toml/v2 v2.0.5 // indirect github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.0.2 // indirect + github.com/polyfloyd/go-errorlint v1.0.5 // indirect github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect github.com/prometheus/procfs v0.7.3 // indirect - github.com/quasilyte/go-ruleguard v0.3.17 // indirect - github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 // indirect + github.com/quasilyte/go-ruleguard v0.3.18 // indirect + github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect github.com/ryancurrah/gomodguard v1.2.4 // indirect github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.13.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.20.0 // indirect github.com/securego/gosec/v2 v2.13.1 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.0 // indirect @@ -132,17 +136,16 @@ require ( github.com/spf13/cobra v1.5.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/spf13/viper v1.12.0 // indirect + github.com/spf13/viper v1.13.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect github.com/stretchr/objx v0.4.0 // indirect github.com/stretchr/testify v1.8.0 // indirect - github.com/subosito/gotenv v1.4.0 // indirect - github.com/sylvia7788/contextcheck v1.0.6 // indirect + github.com/subosito/gotenv v1.4.1 // indirect github.com/tdakkota/asciicheck v0.1.1 // indirect github.com/tetafro/godot v1.4.11 // indirect github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect - github.com/timonwong/logrlint v0.1.0 // indirect + github.com/timonwong/loggercheck v0.9.3 // indirect github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect github.com/ultraware/funlen v0.0.3 // indirect @@ -155,18 +158,18 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.17.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d // indirect + golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect - golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 // indirect - golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab // indirect + golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect + golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/tools v0.1.12 // indirect google.golang.org/protobuf v1.28.0 // indirect - gopkg.in/ini.v1 v1.66.6 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.3.3 // indirect - mvdan.cc/gofumpt v0.3.1 // indirect + mvdan.cc/gofumpt v0.4.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect diff --git a/tools/go.sum b/tools/go.sum index 87d8925a..61b1e2d1 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -38,6 +38,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/Abirdcfly/dupword v0.0.7 h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q= +github.com/Abirdcfly/dupword v0.0.7/go.mod h1:K/4M1kj+Zh39d2aotRwypvasonOyAMH1c/IZJzE0dmk= github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= @@ -52,8 +54,8 @@ github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 h1:+r1rSv4gvYn0wmRjC8X7I github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0/go.mod h1:b3g59n2Y+T5xmcxJL+UEG2f8cQploZm1mR/v6BW0mU0= github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww= github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y= -github.com/OpenPeeDeeP/depguard v1.1.0 h1:pjK9nLPS1FwQYGGpPxoMYpe7qACHOhAWQMQzV71i49o= -github.com/OpenPeeDeeP/depguard v1.1.0/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= +github.com/OpenPeeDeeP/depguard v1.1.1 h1:TSUznLjvp/4IUP+OQ0t/4jF4QUyxIcVX8YnghZdunyA= +github.com/OpenPeeDeeP/depguard v1.1.1/go.mod h1:JtAMzWkmFEzDPyAd+W0NHl1lvpQKTvT9jnRVsohBKpc= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -100,11 +102,11 @@ github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnht github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cristalhq/acmd v0.7.0/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= -github.com/curioswitch/go-reassign v0.1.2 h1:ekM07+z+VFT560Exz4mTv0/s1yU9gem6CJc/tlYpkmI= -github.com/curioswitch/go-reassign v0.1.2/go.mod h1:bFJIHgtTM3hRm2sKXSPkbwNjSFyGURQXyn4IXD2qwfQ= -github.com/daixiang0/gci v0.6.3 h1:wUAqXChk8HbwXn8AfxD9DYSCp9Bpz1L3e6Q4Roe+q9E= -github.com/daixiang0/gci v0.6.3/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= +github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= +github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= +github.com/daixiang0/gci v0.8.0 h1:DzWYUm4+bc+taVUtuq1tsIMb/QFMMYgDIiykSoO98ZU= +github.com/daixiang0/gci v0.8.0/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -126,12 +128,13 @@ github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4 github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= github.com/firefart/nonamedreturns v1.0.4/go.mod h1:TDhe/tjI1BXo48CmYbUduTV7BdIga8MAO/xbKdcVsGI= +github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE= github.com/fsnotify/fsnotify v1.5.4 h1:jRbGcIw6P2Meqdwuo0H1p6JVLbL5DHKAKlYndzMwVZI= github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= -github.com/go-critic/go-critic v0.6.4 h1:tucuG1pvOyYgpBIrVxw0R6gwO42lNa92Aq3VaDoIs+E= -github.com/go-critic/go-critic v0.6.4/go.mod h1:qL5SOlk7NtY6sJPoVCTKDIgzNOxHkkkOCVDyi9wJe1U= +github.com/go-critic/go-critic v0.6.5 h1:fDaR/5GWURljXwF8Eh31T2GZNz9X4jeboS912mWF8Uo= +github.com/go-critic/go-critic v0.6.5/go.mod h1:ezfP/Lh7MA6dBNn4c6ab5ALv3sKnZVLx37tr00uuaOY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -145,17 +148,17 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.0/go.mod h1:vrgyG+5Bxrnz4MZWPF+pI4R8h3qKRjjyvV/DSez4WVQ= -github.com/go-toolsmith/astcopy v1.0.1 h1:l09oBhAPyV74kLJ3ZO31iBU8htZGTwr9LTjuMCyL8go= -github.com/go-toolsmith/astcopy v1.0.1/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= +github.com/go-toolsmith/astcopy v1.0.2 h1:YnWf5Rnh1hUudj11kei53kI57quN/VH6Hp1n+erozn0= +github.com/go-toolsmith/astcopy v1.0.2/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= -github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw= -github.com/go-toolsmith/astequal v1.0.2 h1:+XvaV8zNxua+9+Oa4AHmgmpo4RYAbwr/qjNppLfX2yM= github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= +github.com/go-toolsmith/astequal v1.0.3 h1:+LVdyRatFS+XO78SGV4I3TCEA0AC7fKEGma+fH+674o= +github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= github.com/go-toolsmith/astfmt v1.0.0 h1:A0vDDXt+vsvLEdbMFJAUBI/uTbRw1ffOPnxsILnFL6k= github.com/go-toolsmith/astfmt v1.0.0/go.mod h1:cnWmsOAuq4jJY6Ct5YWlVLmcmLMn1JUPuQIHCY7CJDw= github.com/go-toolsmith/astp v1.0.0 h1:alXE75TXgcmupDsMK1fRAy0YUzLzqPVvBKoyWV+KPXg= github.com/go-toolsmith/astp v1.0.0/go.mod h1:RSyrtpVlfTFGDYRbrjyWP1pYu//tSFcvdYrA8meBmLI= +github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5 h1:eD9POs68PHkwrx7hAB78z1cb6PfGq/jyWn3wJywsH1o= github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM= github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4= github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= @@ -202,10 +205,10 @@ github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9 github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6J5HIP8ZtyMdiDscjMLfRBSPuzVVeo= github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a h1:iR3fYXUjHCR97qWS8ch1y9zPNsgXThGwjKPrYfqMPks= -github.com/golangci/gofmt v0.0.0-20190930125516-244bba706f1a/go.mod h1:9qCChq59u/eW8im404Q2WWTrnBUQKjpNYKMbU4M7EFU= -github.com/golangci/golangci-lint v1.49.0 h1:I8WHOavragDttlLHtSraHn/h39C+R60bEQ5NoGcHQr8= -github.com/golangci/golangci-lint v1.49.0/go.mod h1:+V/7lLv449R6w9mQ3WdV0EKh7Je/jTylMeSwBZcLeWE= +github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= +github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= +github.com/golangci/golangci-lint v1.50.0 h1:+Xmyt8rKLauNLp2gzcxKMN8VNGqGc5Avc2ZLTwIOpEA= +github.com/golangci/golangci-lint v1.50.0/go.mod h1:UqtDvK24R9OizqRF06foPX8opRMzQB0HQK90uI2JgKc= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= @@ -228,9 +231,9 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= @@ -266,6 +269,7 @@ github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3 github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= +github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= @@ -305,13 +309,17 @@ github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7 github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkHAIKE/contextcheck v1.1.2 h1:BYUSG/GhMhqVz//yjl8IkBDlMEws+9DtCmkz18QO1gg= +github.com/kkHAIKE/contextcheck v1.1.2/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= @@ -330,10 +338,13 @@ github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCE github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= +github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= github.com/maratori/testpackage v1.1.0 h1:GJY4wlzQhuBusMF1oahQCBtUV/AQ/k69IZ68vxaac2Q= github.com/maratori/testpackage v1.1.0/go.mod h1:PeAhzU8qkCwdGEMTEupsHJNlQu2gZopMC6RjbhmHeDc= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7RXkts09K+dEBJWakUWwICVqYbA= github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -349,8 +360,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/revive v1.2.3 h1:NzIEEa9+WimQ6q2Ov7OcNeySS/IOcwtkQ8RAh0R5UJ4= -github.com/mgechev/revive v1.2.3/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= +github.com/mgechev/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI= +github.com/mgechev/revive v1.2.4/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -368,13 +379,17 @@ github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81 github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6FxaNu/BnU2OAaLF86eTVhP2hjTB6iMvItA= github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.8.1 h1:0QKNascWv9qIHY7zRoZSxeRr6kuk5aAT3YXLTiDmjTo= -github.com/nishanths/exhaustive v0.8.1/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= +github.com/nishanths/exhaustive v0.8.3 h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMowvhsrM= +github.com/nishanths/exhaustive v0.8.3/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= +github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= @@ -382,8 +397,8 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9 github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/pelletier/go-toml/v2 v2.0.2 h1:+jQXlF3scKIcSEKkdHzXhCTDLPFi5r1wnK6yPS+49Gw= -github.com/pelletier/go-toml/v2 v2.0.2/go.mod h1:MovirKjgVRESsAvNZlAjtFwV867yGuwRkXbG66OzopI= +github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= +github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -393,8 +408,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.0.2 h1:kp1yvHflYhTmw5m3MmBy8SCyQkKPjwDthVuMH0ug6Yk= -github.com/polyfloyd/go-errorlint v1.0.2/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= +github.com/polyfloyd/go-errorlint v1.0.5 h1:AHB5JRCjlmelh9RrLxT9sgzpalIwwq4hqE8EkwIwKdY= +github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -418,19 +433,20 @@ github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1 github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/quasilyte/go-ruleguard v0.3.1-0.20210203134552-1b5a410e1cc8/go.mod h1:KsAh3x0e7Fkpgs+Q9pNLS5XpFSvYCEVl5gP9Pp1xp30= -github.com/quasilyte/go-ruleguard v0.3.17 h1:cDdoaSbQg11LXPDQqiCK54QmQXsEQQCTIgdcpeULGSI= -github.com/quasilyte/go-ruleguard v0.3.17/go.mod h1:sST5PvaR7yb/Az5ksX8oc88usJ4EGjmJv7cK7y3jyig= +github.com/quasilyte/go-ruleguard v0.3.18 h1:sd+abO1PEI9fkYennwzHn9kl3nqP6M5vE7FiOzZ+5CE= +github.com/quasilyte/go-ruleguard v0.3.18/go.mod h1:lOIzcYlgxrQ2sGJ735EHXmf/e9MJ516j16K/Ifcttvs= github.com/quasilyte/go-ruleguard/dsl v0.3.0/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quasilyte/go-ruleguard/dsl v0.3.21/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= github.com/quasilyte/go-ruleguard/rules v0.0.0-20201231183845-9e62ed36efe1/go.mod h1:7JTjp89EGyU1d6XfBiXihJNG37wB2VRkd125Q1u7Plc= github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71/go.mod h1:4cgAphtvu7Ftv7vOT2ZOYhC6CvBxZixcasr8qIOTA50= -github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5 h1:PDWGei+Rf2bBiuZIbZmM20J2ftEy9IeUCHA8HbQqed8= -github.com/quasilyte/gogrep v0.0.0-20220120141003-628d8b3623b5/go.mod h1:wSEyW6O61xRV6zb6My3HxrQ5/8ke7NE2OayqCHa3xRM= +github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f h1:6Gtn2i04RD0gVyYf2/IUMTIs+qYleBt4zxDqkLTcu4U= +github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 h1:L8QM9bvf68pVdQ3bCFZMDmnt9yqcMBro1pC7F+IPYMY= github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= @@ -440,8 +456,8 @@ github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3 github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.13.0 h1:uObNudVEEHf6JbOJy5bgKJloA1bWjxR9fwgNFpPzKnI= -github.com/sashamelentyev/usestdlibvars v1.13.0/go.mod h1:D2Wb7niIYmTB+gB8z7kh8tyP5ccof1dQ+SFk+WW5NtY= +github.com/sashamelentyev/usestdlibvars v1.20.0 h1:K6CXjqqtSYSsuyRDDC7Sjn6vTMLiSJa4ZmDkiokoqtw= +github.com/sashamelentyev/usestdlibvars v1.20.0/go.mod h1:0GaP+ecfZMXShS0A94CJn6aEuPRILv8h/VuWI9n1ygg= github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= @@ -473,8 +489,8 @@ github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmq github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= -github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/spf13/viper v1.13.0 h1:BWSJ/M+f+3nmdz9bxB+bWX28kkALN2ok11D0rSo8EJU= +github.com/spf13/viper v1.13.0/go.mod h1:Icm2xNL3/8uyh/wFuB1jI7TiTNKp8632Nwegu+zgdYw= github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= @@ -490,23 +506,22 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.4.0 h1:yAzM1+SmVcz5R4tXGsNMu1jUl2aOJXoiWUCEwwnGrvs= -github.com/subosito/gotenv v1.4.0/go.mod h1:mZd6rFysKEcUhUHXJk0C/08wAgyDBFuwEYL7vWWGaGo= -github.com/sylvia7788/contextcheck v1.0.6 h1:o2EZgVPyMKE/Mtoqym61DInKEjwEbsmyoxg3VrmjNO4= -github.com/sylvia7788/contextcheck v1.0.6/go.mod h1:9XDxwvxyuKD+8N+a7Gs7bfWLityh5t70g/GjdEt2N2M= +github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= +github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= +github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= -github.com/timonwong/logrlint v0.1.0 h1:phZCcypL/vtx6cGxObJgWZ5wexZF5SXFPLOM+ru0e/M= -github.com/timonwong/logrlint v0.1.0/go.mod h1:Zleg4Gw+kRxNej+Ra7o+tEaW5k1qthTaYKU7rSD39LU= +github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= +github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw= github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M= github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= @@ -564,8 +579,8 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d h1:+W8Qf4iJtMGKkyAygcKohjxTk4JPsL9DpzApJ22m5Ic= -golang.org/x/exp/typeparams v0.0.0-20220613132600-b0d781184e0d/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk= +golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -630,6 +645,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -652,8 +668,9 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc= +golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -709,8 +726,9 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab h1:2QkjZIsXupsJbJIdSjjUOgWK3aEtzyuh2mPt3l/CkeU= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc= +golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -905,10 +923,11 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLks gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/ini.v1 v1.66.6 h1:LATuAqN/shcYAOkv3wl2L4rkaKqkcgTBQjOyYDvcPKI= -gopkg.in/ini.v1 v1.66.6/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -930,8 +949,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= -mvdan.cc/gofumpt v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8= -mvdan.cc/gofumpt v0.3.1/go.mod h1:w3ymliuxvzVx8DAutBnVyDqYb1Niy/yCJt/lk821YCE= +mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= +mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= From 0f80589ee32b1661adcf7cc8cf2e7498b56733f0 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 24 Oct 2022 12:44:44 +1100 Subject: [PATCH 110/172] Complete refactoring of signal collection logic (#220) Turns the signal collection code into a library that abstracts away the work required to collect signals. This makes it easy to reuse between different binaries. * More refactoring - move signal collection into the collector package. * Simplify the result.Writer interface. * Relocate the result package into internal/signalio. Signed-off-by: Caleb Brown --- cmd/collect_signals/main.go | 101 +++------ internal/collector/collector.go | 124 ++++++++++ internal/collector/config.go | 177 +++++++++++++++ internal/collector/config_test.go | 86 +++++++ internal/collector/github/factory.go | 14 +- internal/collector/projectrepo/repo.go | 6 +- internal/collector/projectrepo/resolver.go | 23 +- internal/collector/registry.go | 45 +--- internal/githubapi/client.go | 14 +- internal/githubapi/errors.go | 68 ++++++ internal/githubapi/roundtripper.go | 44 +++- internal/githubapi/roundtripper_test.go | 213 +++++++++++++++++- .../result => internal/signalio}/csv.go | 46 ++-- .../emitter.go => internal/signalio/writer.go | 15 +- 14 files changed, 786 insertions(+), 190 deletions(-) create mode 100644 internal/collector/collector.go create mode 100644 internal/collector/config.go create mode 100644 internal/collector/config_test.go rename {cmd/collect_signals/result => internal/signalio}/csv.go (77%) rename cmd/collect_signals/result/emitter.go => internal/signalio/writer.go (67%) diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index b4302510..82893a8a 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -17,6 +17,7 @@ package main import ( "bufio" "context" + "errors" "flag" "fmt" "net/http" @@ -25,22 +26,14 @@ import ( "path" "strings" - "github.com/go-logr/zapr" - "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" - sclog "github.com/ossf/scorecard/v4/log" "go.uber.org/zap" "go.uber.org/zap/zapcore" - "github.com/ossf/criticality_score/cmd/collect_signals/result" "github.com/ossf/criticality_score/internal/collector" - "github.com/ossf/criticality_score/internal/collector/depsdev" - "github.com/ossf/criticality_score/internal/collector/github" - "github.com/ossf/criticality_score/internal/collector/githubmentions" - "github.com/ossf/criticality_score/internal/collector/projectrepo" - "github.com/ossf/criticality_score/internal/githubapi" "github.com/ossf/criticality_score/internal/infile" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/signalio" "github.com/ossf/criticality_score/internal/workerpool" ) @@ -49,7 +42,7 @@ const defaultLogLevel = zapcore.InfoLevel var ( gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") - depsdevDatasetFlag = flag.String("depsdev-dataset", depsdev.DefaultDatasetName, "the BigQuery dataset name to use.") + depsdevDatasetFlag = flag.String("depsdev-dataset", collector.DefaultGCPDatasetName, "the BigQuery dataset name to use.") workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") logLevel = defaultLogLevel logEnv log.Env @@ -71,63 +64,27 @@ func init() { } } -func handleRepo(ctx context.Context, logger *zap.Logger, u *url.URL, out result.Writer) { - r, err := projectrepo.Resolve(ctx, u) +func handleRepo(ctx context.Context, logger *zap.Logger, c *collector.Collector, u *url.URL, out signalio.Writer) { + ss, err := c.Collect(ctx, u) if err != nil { - logger.With(zap.Error(err)).Warn("Failed to create project") - // TODO: we should have an error that indicates that the URL/Project - // should be skipped/ignored. - return // TODO: add a flag to continue or abort on failure - } - logger = logger.With(zap.String("canonical_url", r.URL().String())) - - // TODO: p.URL() should be checked to see if it has already been processed. - - // Collect the signals for the given project - logger.Info("Collecting") - ss, err := collector.Collect(ctx, r) - if err != nil { - logger.With( - zap.Error(err), - ).Error("Failed to collect signals for project") - os.Exit(1) // TODO: add a flag to continue or abort on failure - } - - rec := out.Record() - for _, s := range ss { - if err := rec.WriteSignalSet(s); err != nil { + if errors.Is(err, collector.ErrUncollectableRepo) { logger.With( zap.Error(err), - ).Error("Failed to write signal set") - os.Exit(1) // TODO: add a flag to continue or abort on failure + ).Warn("Repo cannot be collected") + return } - } - if err := rec.Done(); err != nil { logger.With( zap.Error(err), - ).Error("Failed to complete record") - os.Exit(1) // TODO: add a flag to continue or abort on failure + ).Error("Failed to collect signals for repo") + os.Exit(1) // TODO: pass up the error } -} -func initSources(ctx context.Context, logger *zap.Logger, ghClient *githubapi.Client) error { - collector.Register(&github.RepoSource{}) - collector.Register(&github.IssuesSource{}) - collector.Register(githubmentions.NewSource(ghClient)) - - if *depsdevDisableFlag { - // deps.dev collection source has been disabled, so skip it. - logger.Warn("deps.dev signal source is disabled.") - } else { - ddsource, err := depsdev.NewSource(ctx, logger, *gcpProjectFlag, *depsdevDatasetFlag) - if err != nil { - return fmt.Errorf("init deps.dev source: %w", err) - } - logger.Info("deps.dev signal source enabled") - collector.Register(ddsource) + if err := out.WriteSignals(ss); err != nil { + logger.With( + zap.Error(err), + ).Error("Failed to write signal set") + os.Exit(1) // TODO: pass up the error } - - return nil } func main() { @@ -139,10 +96,6 @@ func main() { } defer logger.Sync() - // roundtripper requires us to use the scorecard logger. - innerLogger := zapr.NewLogger(logger) - scLogger := &sclog.Logger{Logger: &innerLogger} - // Complete the validation of args if flag.NArg() != 2 { logger.Error("Must have one input file and one output file specified.") @@ -154,22 +107,20 @@ func main() { // Bump the # idle conns per host http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = *workersFlag * 5 - // Prepare a client for communicating with GitHub's GraphQLv4 API and Restv3 API - rt := githubapi.NewRoundTripper(roundtripper.NewTransport(ctx, scLogger), logger) - httpClient := &http.Client{ - Transport: rt, + opts := []collector.Option{ + collector.EnableAllSources(), + collector.GCPProject(*gcpProjectFlag), + collector.GCPDatasetName(*depsdevDatasetFlag), + } + if *depsdevDisableFlag { + opts = append(opts, collector.DisableSource(collector.SourceTypeDepsDev)) } - ghClient := githubapi.NewClient(httpClient) - - // Register all the Repo factories. - projectrepo.Register(github.NewRepoFactory(ghClient, logger)) - // Register all the sources that are supported. - err = initSources(ctx, logger, ghClient) + c, err := collector.New(ctx, logger, opts...) if err != nil { logger.With( zap.Error(err), - ).Error("Failed to initialize sources") + ).Error("Failed to create collector") os.Exit(2) } @@ -199,14 +150,14 @@ func main() { defer w.Close() // Prepare the output writer - out := result.NewCsvWriter(w, collector.EmptySets()) + out := signalio.CsvWriter(w, c.EmptySets()) // Start the workers that process a channel of repo urls. repos := make(chan *url.URL) wait := workerpool.WorkerPool(*workersFlag, func(worker int) { innerLogger := logger.With(zap.Int("worker", worker)) for u := range repos { - handleRepo(ctx, innerLogger.With(zap.String("url", u.String())), u, out) + handleRepo(ctx, innerLogger.With(zap.String("url", u.String())), c, u, out) } }) diff --git a/internal/collector/collector.go b/internal/collector/collector.go new file mode 100644 index 00000000..2d43ba4d --- /dev/null +++ b/internal/collector/collector.go @@ -0,0 +1,124 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +// Package collector is used to collect signals for a given repository from a +// variety of sources. +package collector + +import ( + "context" + "errors" + "fmt" + "net/url" + + "go.uber.org/zap" + + "github.com/ossf/criticality_score/internal/collector/depsdev" + "github.com/ossf/criticality_score/internal/collector/github" + "github.com/ossf/criticality_score/internal/collector/githubmentions" + "github.com/ossf/criticality_score/internal/collector/projectrepo" + "github.com/ossf/criticality_score/internal/collector/signal" + "github.com/ossf/criticality_score/internal/githubapi" +) + +// ErrUncollectableRepo is the base error returned when there is a problem with +// the repo url passed in to be collected. +// +// For example, the URL may point to an invalid repository host, or the URL +// may point to a repo that is inaccessible or missing. +var ErrUncollectableRepo = errors.New("repo failed") + +// ErrRepoNotFound wraps ErrUncollectableRepo and is used when a repo cannot be +// found for collection. +var ErrRepoNotFound = fmt.Errorf("%w: not found", ErrUncollectableRepo) + +// ErrUnsupportedURL wraps ErrUncollectableRepo and is used when a repo url +// does not match any of the supported hosts. +var ErrUnsupportedURL = fmt.Errorf("%w: unsupported url", ErrUncollectableRepo) + +type Collector struct { + config *Config + logger *zap.Logger + resolver *projectrepo.Resolver + registry *registry +} + +func New(ctx context.Context, logger *zap.Logger, opts ...Option) (*Collector, error) { + c := &Collector{ + config: makeConfig(ctx, logger, opts...), + logger: logger, + resolver: &projectrepo.Resolver{}, + registry: newRegistry(), + } + + ghClient := githubapi.NewClient(c.config.gitHubHTTPClient) + + // Register all the Repo factories. + c.resolver.Register(github.NewRepoFactory(ghClient, logger)) + + // Register all the sources that are supported and enabled. + if c.config.IsEnabled(SourceTypeGithubRepo) { + c.registry.Register(&github.RepoSource{}) + } + if c.config.IsEnabled(SourceTypeGithubIssues) { + c.registry.Register(&github.IssuesSource{}) + } + if c.config.IsEnabled(SourceTypeGitHubMentions) { + c.registry.Register(githubmentions.NewSource(ghClient)) + } + if !c.config.IsEnabled(SourceTypeDepsDev) { + // deps.dev collection source has been disabled, so skip it. + logger.Warn("deps.dev signal source is disabled.") + } else { + ddsource, err := depsdev.NewSource(ctx, logger, c.config.gcpProject, c.config.gcpDatasetName) + if err != nil { + return nil, fmt.Errorf("init deps.dev source: %w", err) + } + logger.Info("deps.dev signal source enabled") + c.registry.Register(ddsource) + } + + return c, nil +} + +// EmptySet returns all the empty instances of signal Sets that are used for +// determining the namespace and signals supported by the Source. +func (c *Collector) EmptySets() []signal.Set { + return c.registry.EmptySets() +} + +// Collect gathers and returns all the signals for the given project repo url. +func (c *Collector) Collect(ctx context.Context, u *url.URL) ([]signal.Set, error) { + l := c.config.logger.With(zap.String("url", u.String())) + + repo, err := c.resolver.Resolve(ctx, u) + if err != nil { + switch { + case errors.Is(err, projectrepo.ErrNoFactoryFound): + return nil, fmt.Errorf("%w: %s", ErrUnsupportedURL, u) + case errors.Is(err, projectrepo.ErrNoRepoFound): + return nil, fmt.Errorf("%w: %s", ErrRepoNotFound, u) + default: + return nil, fmt.Errorf("resolving project: %w", err) + } + } + l = l.With(zap.String("canonical_url", repo.URL().String())) + + l.Info("Collecting") + ss, err := c.registry.Collect(ctx, repo) + if err != nil { + return nil, fmt.Errorf("collecting project: %w", err) + } + return ss, nil +} diff --git a/internal/collector/config.go b/internal/collector/config.go new file mode 100644 index 00000000..4b4fc300 --- /dev/null +++ b/internal/collector/config.go @@ -0,0 +1,177 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package collector + +import ( + "context" + "fmt" + "net/http" + + "github.com/go-logr/zapr" + "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" + sclog "github.com/ossf/scorecard/v4/log" + "go.uber.org/zap" + + "github.com/ossf/criticality_score/internal/githubapi" +) + +// DefaultGCPDatasetName is the default name to use for GCP BigQuery Datasets. +const DefaultGCPDatasetName = "criticality_score_data" + +// SourceType is used to identify the various sources signals can be collected +// from. +type SourceType int + +const ( + SourceTypeGithubRepo SourceType = iota + SourceTypeGithubIssues + SourceTypeGitHubMentions + SourceTypeDepsDev +) + +// String implements the fmt.Stringer interface. +func (t SourceType) String() string { + switch t { + case SourceTypeGithubRepo: + return "SourceTypeGithubRepo" + case SourceTypeGithubIssues: + return "SourceTypeGithubIssues" + case SourceTypeGitHubMentions: + return "SourceTypeGitHubMentions" + case SourceTypeDepsDev: + return "SourceTypeDepsDev" + default: + return fmt.Sprintf("Unknown SourceType %d", int(t)) + } +} + +type sourceStatus int + +const ( + sourceStatusDisabled sourceStatus = iota + sourceStatusEnabled +) + +//nolint:govet +type Config struct { + logger *zap.Logger + + gitHubHTTPClient *http.Client + + gcpProject string + gcpDatasetName string + + sourceStatuses map[SourceType]sourceStatus + defaultSourceStatus sourceStatus +} + +// Option is an interface used to change the config. +type Option interface{ set(*Config) } + +// option implements Option interface. +type option func(*Config) + +// set implements the Option interface. +func (o option) set(c *Config) { o(c) } + +func makeConfig(ctx context.Context, logger *zap.Logger, opts ...Option) *Config { + c := &Config{ + logger: logger, + defaultSourceStatus: sourceStatusEnabled, + sourceStatuses: make(map[SourceType]sourceStatus), + gitHubHTTPClient: defaultGitHubHTTPClient(ctx, logger), + gcpProject: "", + gcpDatasetName: DefaultGCPDatasetName, + } + + for _, opt := range opts { + opt.set(c) + } + + return c +} + +// IsEnabled returns true if the given SourceType is enabled. +func (c *Config) IsEnabled(s SourceType) bool { + if status, ok := c.sourceStatuses[s]; ok { + return status == sourceStatusEnabled + } else { + return c.defaultSourceStatus == sourceStatusEnabled + } +} + +func defaultGitHubHTTPClient(ctx context.Context, logger *zap.Logger) *http.Client { + // roundtripper requires us to use the scorecard logger. + innerLogger := zapr.NewLogger(logger) + scLogger := &sclog.Logger{Logger: &innerLogger} + + // Prepare a client for communicating with GitHub's GraphQLv4 API and Restv3 API + rt := githubapi.NewRetryRoundTripper(roundtripper.NewTransport(ctx, scLogger), logger) + + return &http.Client{ + Transport: rt, + } +} + +// EnableAllSources enables all SourceTypes for collection. +// +// All data sources will be used for collection unless explicitly disabled +// with DisableSource. +func EnableAllSources() Option { + return option(func(c *Config) { + c.defaultSourceStatus = sourceStatusEnabled + }) +} + +// DisableAllSources will disable all SourceTypes for collection. +// +// No data sources will be used for collection unless explicitly enabled +// with EnableSource. +func DisableAllSources() Option { + return option(func(c *Config) { + c.defaultSourceStatus = sourceStatusDisabled + }) +} + +// EnableSource will enable the supplied SourceType for collection. +func EnableSource(s SourceType) Option { + return option(func(c *Config) { + c.sourceStatuses[s] = sourceStatusEnabled + }) +} + +// DisableSource will enable the supplied SourceType for collection. +func DisableSource(s SourceType) Option { + return option(func(c *Config) { + c.sourceStatuses[s] = sourceStatusDisabled + }) +} + +// GCPProject is used to set the ID of the GCP project used for sources that +// depend on GCP. +// +// If not supplied, the currently configured project will be used. +func GCPProject(n string) Option { + return option(func(c *Config) { + c.gcpProject = n + }) +} + +// GCPDatasetName overrides DefaultGCPDatasetName with the supplied dataset name. +func GCPDatasetName(n string) Option { + return option(func(c *Config) { + c.gcpDatasetName = n + }) +} diff --git a/internal/collector/config_test.go b/internal/collector/config_test.go new file mode 100644 index 00000000..8a22d0ff --- /dev/null +++ b/internal/collector/config_test.go @@ -0,0 +1,86 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package collector + +import ( + "context" + "testing" + + "go.uber.org/zap/zaptest" +) + +var allSourceTypes = []SourceType{ + SourceTypeGithubRepo, + SourceTypeGithubIssues, + SourceTypeGitHubMentions, + SourceTypeDepsDev, +} + +func TestIsEnabled_AllEnabled(t *testing.T) { + c := makeTestConfig(t, EnableAllSources()) + for _, sourceType := range allSourceTypes { + t.Run(sourceType.String(), func(t *testing.T) { + if !c.IsEnabled(sourceType) { + t.Fatalf("IsEnabled(%s) = false, want true", sourceType) + } + }) + } +} + +func TestIsEnabled_AllDisabled(t *testing.T) { + c := makeTestConfig(t, DisableAllSources()) + for _, sourceType := range allSourceTypes { + t.Run(sourceType.String(), func(t *testing.T) { + if c.IsEnabled(sourceType) { + t.Fatalf("IsEnabled(%s) = true, want false", sourceType) + } + }) + } +} + +func TestIsEnabled_OneDisabled(t *testing.T) { + c := makeTestConfig(t, EnableAllSources(), DisableSource(SourceTypeDepsDev)) + if c.IsEnabled(SourceTypeDepsDev) { + t.Fatalf("IsEnabled(%s) = true, want false", SourceTypeDepsDev) + } +} + +func TestIsEnabled_OneEnabled(t *testing.T) { + c := makeTestConfig(t, DisableAllSources(), EnableSource(SourceTypeDepsDev)) + if !c.IsEnabled(SourceTypeDepsDev) { + t.Fatalf("IsEnabled(%s) = false, want true", SourceTypeDepsDev) + } +} + +func TestGCPProject(t *testing.T) { + want := "my-project-id" + c := makeTestConfig(t, GCPProject(want)) + if c.gcpProject != want { + t.Fatalf("config.gcpProject = %q, want %q", c.gcpProject, want) + } +} + +func TestGCPDatasetName(t *testing.T) { + want := "my-dataset-name" + c := makeTestConfig(t, GCPDatasetName(want)) + if c.gcpDatasetName != want { + t.Fatalf("config.gcpDatasetName = %q, want %q", c.gcpDatasetName, want) + } +} + +func makeTestConfig(t *testing.T, opts ...Option) *Config { + t.Helper() + return makeConfig(context.Background(), zaptest.NewLogger(t), opts...) +} diff --git a/internal/collector/github/factory.go b/internal/collector/github/factory.go index 05a90ed3..e8f53dfd 100644 --- a/internal/collector/github/factory.go +++ b/internal/collector/github/factory.go @@ -16,6 +16,8 @@ package github import ( "context" + "errors" + "fmt" "net/url" "go.uber.org/zap" @@ -37,15 +39,19 @@ func NewRepoFactory(client *githubapi.Client, logger *zap.Logger) projectrepo.Fa } func (f *factory) New(ctx context.Context, u *url.URL) (projectrepo.Repo, error) { - p := &repo{ + r := &repo{ client: f.client, origURL: u, logger: f.logger.With(zap.String("url", u.String())), } - if err := p.init(ctx); err != nil { - return nil, err + if err := r.init(ctx); err != nil { + if errors.Is(err, githubapi.ErrGraphQLNotFound) { + return nil, fmt.Errorf("%w: %s", projectrepo.ErrNoRepoFound, u) + } else { + return nil, err + } } - return p, nil + return r, nil } func (f *factory) Match(u *url.URL) bool { diff --git a/internal/collector/projectrepo/repo.go b/internal/collector/projectrepo/repo.go index 0a377feb..3663b373 100644 --- a/internal/collector/projectrepo/repo.go +++ b/internal/collector/projectrepo/repo.go @@ -28,8 +28,10 @@ type Repo interface { type Factory interface { // New returns a new instance of Repo for the supplied URL. // - // If the project is not valid for use, or there is an issue creating the - // the Project will be nil and an error will be returned. + // If the project can not be found, the error NoRepoFound will be returned. + // + // If the project is not valid for use, or there is any other issue creating + // the Repo, Repo will be nil and an error will be returned. New(context.Context, *url.URL) (Repo, error) // Match returns true if this factory can create a new instance of Repo diff --git a/internal/collector/projectrepo/resolver.go b/internal/collector/projectrepo/resolver.go index b092580c..6f356cce 100644 --- a/internal/collector/projectrepo/resolver.go +++ b/internal/collector/projectrepo/resolver.go @@ -17,14 +17,17 @@ package projectrepo import ( "context" "errors" + "fmt" "net/url" ) -// ErrorNotFound is returned when there is no factory that can be used for a -// given URL. -var ErrorNotFound = errors.New("factory not found for url") +// ErrNoFactoryFound is returned when there is no factory that can be used for +// a given URL. +var ErrNoFactoryFound = errors.New("factory not found") -var globalResolver = &Resolver{} +// ErrNoRepoFound is returned when a factory cannot create a Repo for a given +// URL. +var ErrNoRepoFound = errors.New("repo not found") // Resolver is used to resolve a Repo url against a set of Factory instances // registered with the resolver. @@ -56,17 +59,7 @@ func (r *Resolver) Register(f Factory) { func (r *Resolver) Resolve(ctx context.Context, u *url.URL) (Repo, error) { f := r.findFactory(u) if f == nil { - return nil, ErrorNotFound + return nil, fmt.Errorf("%w: %s", ErrNoFactoryFound, u) } return f.New(ctx, u) } - -// Register the factory f with the global resolver. -func Register(f Factory) { - globalResolver.Register(f) -} - -// Resolve the given url u with the global resolver. -func Resolve(ctx context.Context, u *url.URL) (Repo, error) { - return globalResolver.Resolve(ctx, u) -} diff --git a/internal/collector/registry.go b/internal/collector/registry.go index 02706d78..a807d899 100644 --- a/internal/collector/registry.go +++ b/internal/collector/registry.go @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package collector defines a registry for using signal sources together. package collector import ( @@ -26,19 +25,17 @@ import ( // empty is a convenience wrapper for the empty struct. type empty struct{} -var globalRegistry = NewRegistry() - -type Registry struct { +type registry struct { ss []signal.Source } -// NewRegistry creates a new instance of Registry. -func NewRegistry() *Registry { - return &Registry{} +// newRegistry creates a new instance of registry. +func newRegistry() *registry { + return ®istry{} } // containsSource returns true if c has already been registered. -func (r *Registry) containsSource(s signal.Source) bool { +func (r *registry) containsSource(s signal.Source) bool { for _, regS := range r.ss { if regS == s { return true @@ -53,7 +50,7 @@ func (r *Registry) containsSource(s signal.Source) bool { // Source has already been added. // // The order which Sources are added is preserved. -func (r *Registry) Register(s signal.Source) { +func (r *registry) Register(s signal.Source) { validateSource(s) if r.containsSource(s) { panic(fmt.Sprintf("source %s has already been registered", s.EmptySet().Namespace())) @@ -64,7 +61,7 @@ func (r *Registry) Register(s signal.Source) { r.ss = append(r.ss, s) } -func (r *Registry) sourcesForRepository(repo projectrepo.Repo) []signal.Source { +func (r *registry) sourcesForRepository(repo projectrepo.Repo) []signal.Source { // Check for duplicates using a map to preserve the insertion order // of the sources. exists := make(map[signal.Namespace]empty) @@ -92,7 +89,7 @@ func (r *Registry) sourcesForRepository(repo projectrepo.Repo) []signal.Source { // The order of each empty Set is the same as the order of registration. If two // Sources return a Set with the same Namespace, only the first Set will be // included. -func (r *Registry) EmptySets() []signal.Set { +func (r *registry) EmptySets() []signal.Set { exists := make(map[signal.Namespace]empty) var ss []signal.Set for _, c := range r.ss { @@ -106,7 +103,7 @@ func (r *Registry) EmptySets() []signal.Set { } // Collect will collect all the signals for the given repo. -func (r *Registry) Collect(ctx context.Context, repo projectrepo.Repo) ([]signal.Set, error) { +func (r *registry) Collect(ctx context.Context, repo projectrepo.Repo) ([]signal.Set, error) { cs := r.sourcesForRepository(repo) var ss []signal.Set for _, c := range cs { @@ -119,30 +116,6 @@ func (r *Registry) Collect(ctx context.Context, repo projectrepo.Repo) ([]signal return ss, nil } -// Register registers the source with the global registry for use during -// calls to Collect(). -// -// See Registry.Register(). -func Register(s signal.Source) { - globalRegistry.Register(s) -} - -// EmptySet returns all the empty signal Sets for all the Sources registered -// with the global registry. -// -// See Registry.EmptySets(). -func EmptySets() []signal.Set { - return globalRegistry.EmptySets() -} - -// Collect collects all the signals for the given repo using the Sources -// registered with the global registry. -// -// See Registry.Collect(). -func Collect(ctx context.Context, r projectrepo.Repo) ([]signal.Set, error) { - return globalRegistry.Collect(ctx, r) -} - func validateSource(s signal.Source) { // TODO - ensure a source with the same Namespace as another use // the same signal.Set diff --git a/internal/githubapi/client.go b/internal/githubapi/client.go index a0bf3590..0b0b5490 100644 --- a/internal/githubapi/client.go +++ b/internal/githubapi/client.go @@ -21,24 +21,30 @@ import ( "github.com/shurcooL/githubv4" ) +// Client provides simple access to GitHub's REST and GraphQL APIs. type Client struct { restClient *github.Client graphClient *githubv4.Client } +// NewClient creates a new instances of Client. func NewClient(client *http.Client) *Client { - c := &Client{ + // Wrap the Transport for the GraphQL client to produce more useful errors. + graphClient := *client // deref to copy the struct + graphClient.Transport = &graphQLRoundTripper{inner: client.Transport} + + return &Client{ restClient: github.NewClient(client), - graphClient: githubv4.NewClient(client), + graphClient: githubv4.NewClient(&graphClient), } - - return c } +// Rest returns a client for communicating with GitHub's REST API. func (c *Client) Rest() *github.Client { return c.restClient } +// GraphQL returns a client for communicating with GitHub's GraphQL API. func (c *Client) GraphQL() *githubv4.Client { return c.graphClient } diff --git a/internal/githubapi/errors.go b/internal/githubapi/errors.go index 595f6b41..f5938ca8 100644 --- a/internal/githubapi/errors.go +++ b/internal/githubapi/errors.go @@ -16,6 +16,7 @@ package githubapi import ( "errors" + "fmt" "github.com/google/go-github/v47/github" ) @@ -36,3 +37,70 @@ func ErrorResponseStatusCode(err error) int { } return e.Response.StatusCode } + +// ErrGraphQLNotFound is an error used to test when GitHub GraphQL query +// returns a single error with the type "NOT_FOUND". +// +// It should be used with errors.Is. +var ErrGraphQLNotFound = errors.New("GraphQL resource not found") + +// gitHubGraphQLNotFoundType matches the NOT_FOUND type field returned +// in GitHub's GraphQL errors. +// +// GraphQL errors are required to have a Message, and optional Path and +// Locations. Type is a non-standard field available on GitHub's API. +const gitHubGraphQLNotFoundType = "NOT_FOUND" + +// GraphQLError stores the error result from a GitHub GraphQL query. +type GraphQLError struct { + Message string + Type string // GitHub specific GraphQL error field + Locations []struct { + Line int + Column int + } +} + +// GraphQLErrors wraps all the errors returned by a GraphQL response. +type GraphQLErrors struct { + errors []GraphQLError +} + +// Error implements error interface. +func (e *GraphQLErrors) Error() string { + switch len(e.errors) { + case 0: + panic("no errors found") + case 1: + return e.errors[0].Message + default: + return fmt.Sprintf("%d GraphQL errors", len(e.errors)) + } +} + +// HasType returns true if one of the errors matches the supplied type. +func (e *GraphQLErrors) HasType(t string) bool { + for _, anError := range e.errors { + if anError.Type == t { + return true + } + } + return false +} + +// Errors returns a slice with each Error returned by the GraphQL API. +func (e *GraphQLErrors) Errors() []GraphQLError { + return e.errors +} + +// Is implements the errors.Is interface. +func (e *GraphQLErrors) Is(target error) bool { + if target == e { + // Identity test is always true. + return true + } + if target == ErrGraphQLNotFound { + return len(e.errors) == 1 && e.HasType(gitHubGraphQLNotFoundType) + } + return false +} diff --git a/internal/githubapi/roundtripper.go b/internal/githubapi/roundtripper.go index 8a7497cf..898314da 100644 --- a/internal/githubapi/roundtripper.go +++ b/internal/githubapi/roundtripper.go @@ -39,7 +39,7 @@ var ( issueCommentsRe = regexp.MustCompile("^repos/[^/]+/[^/]+/issues/comments$") ) -func NewRoundTripper(rt http.RoundTripper, logger *zap.Logger) http.RoundTripper { +func NewRetryRoundTripper(rt http.RoundTripper, logger *zap.Logger) http.RoundTripper { s := &strategies{logger: logger} return retry.NewRoundTripper(rt, retry.InitialDelay(2*time.Minute), @@ -153,3 +153,45 @@ func (s *strategies) RetryAfter(r *http.Response) time.Duration { } return 0 } + +// graphQLRoundTripper is used to make GraphQL errors produced by the GitHub +// GraphQL accessible. +// +// This allows the detection of NOT_FOUND responses, so we can accurately +// tell the difference between an error due to connectivity or server +// issues and a repository not existing. +type graphQLRoundTripper struct { + inner http.RoundTripper +} + +// RoundTrip implements the http.RoundTripper interface. +func (rt *graphQLRoundTripper) RoundTrip(r *http.Request) (*http.Response, error) { + resp, err := rt.inner.RoundTrip(r) + if err != nil || resp.StatusCode != http.StatusOK { + return resp, err + } + // Read the body in and close it. + body, err := io.ReadAll(resp.Body) + resp.Body.Close() + if err != nil { + // TODO: Do we need to do something with this error? + return nil, err + } + + var out struct { + Data *json.RawMessage + Errors []GraphQLError + } + err = json.Unmarshal(body, &out) + if err != nil { + // TODO: Do we need to do something with this error? + return nil, err + } + if len(out.Errors) > 0 { + return nil, &GraphQLErrors{errors: out.Errors} + } + + // Reset the body so that others can read it as well. + resp.Body = io.NopCloser(bytes.NewBuffer(body)) + return resp, nil +} diff --git a/internal/githubapi/roundtripper_test.go b/internal/githubapi/roundtripper_test.go index dc7bbc71..068d7a31 100644 --- a/internal/githubapi/roundtripper_test.go +++ b/internal/githubapi/roundtripper_test.go @@ -15,13 +15,16 @@ package githubapi import ( - "bytes" + "context" + "encoding/json" "errors" "fmt" "io" "net/http" "net/url" + "strings" "testing" + "testing/iotest" "time" "go.uber.org/zap/zaptest" @@ -141,7 +144,7 @@ func TestServerError400(t *testing.T) { r := &http.Response{ Header: http.Header{http.CanonicalHeaderKey("Content-Type"): {"text/html"}}, StatusCode: http.StatusBadRequest, - Body: io.NopCloser(bytes.NewBuffer([]byte(`This is an error`))), + Body: io.NopCloser(strings.NewReader(`This is an error`)), } s, err := newTestStrategies(t).ServerError400(r) if err != nil { @@ -156,7 +159,7 @@ func TestServerError400_NoMatchingString(t *testing.T) { r := &http.Response{ Header: http.Header{http.CanonicalHeaderKey("Content-Type"): {"text/html"}}, StatusCode: http.StatusBadRequest, - Body: io.NopCloser(bytes.NewBuffer([]byte(`Web PageWeb PageThis is an error`))), + Body: io.NopCloser(strings.NewReader(`This is an error`)), } s, err := newTestStrategies(t).ServerError400(r) if err != nil { @@ -240,8 +243,8 @@ func TestServerError400_StatusCodes(t *testing.T) { func TestSecondaryRateLimit(t *testing.T) { r := &http.Response{ StatusCode: http.StatusForbidden, - Body: io.NopCloser(bytes.NewBuffer( - []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL)))), + Body: io.NopCloser(strings.NewReader( + fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL))), } s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { @@ -255,8 +258,8 @@ func TestSecondaryRateLimit(t *testing.T) { func TestSecondaryRateLimit_AbuseUrl(t *testing.T) { r := &http.Response{ StatusCode: http.StatusForbidden, - Body: io.NopCloser(bytes.NewBuffer( - []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testAbuseRateLimitDocURL)))), + Body: io.NopCloser(strings.NewReader( + fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testAbuseRateLimitDocURL))), } s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { @@ -270,7 +273,7 @@ func TestSecondaryRateLimit_AbuseUrl(t *testing.T) { func TestSecondaryRateLimit_OtherUrl(t *testing.T) { r := &http.Response{ StatusCode: http.StatusForbidden, - Body: io.NopCloser(bytes.NewBuffer([]byte(`{"message": "test", "documentation_url": "https://example.org/"}`))), + Body: io.NopCloser(strings.NewReader(`{"message": "test", "documentation_url": "https://example.org/"}`)), } s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { @@ -322,8 +325,8 @@ func TestSecondaryRateLimit_StatusCodes(t *testing.T) { t.Run(fmt.Sprintf("status %d", test.statusCode), func(t *testing.T) { r := &http.Response{ StatusCode: test.statusCode, - Body: io.NopCloser(bytes.NewBuffer( - []byte(fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL)))), + Body: io.NopCloser(strings.NewReader( + fmt.Sprintf(`{"message": "test", "documentation_url": "%s"}`, testSecondaryRateLimitDocURL))), } s, err := newTestStrategies(t).SecondaryRateLimit(r) if err != nil { @@ -335,3 +338,189 @@ func TestSecondaryRateLimit_StatusCodes(t *testing.T) { }) } } + +type testRoundTripperFunc func(*http.Request) (*http.Response, error) + +func (t testRoundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) { + return t(r) +} + +func TestGraphQLRoundTripper_InnerError(t *testing.T) { + want := errors.New("inner error") + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return nil, want + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); !errors.Is(err, want) { + t.Fatalf("RoundTrip() returned %v, want %v", err, want) + } +} + +func TestGraphQLRoundTripper_Non200Response(t *testing.T) { + want := &http.Response{ + StatusCode: http.StatusBadRequest, + Body: io.NopCloser(strings.NewReader("")), + } + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return want, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if resp, err := rt.RoundTrip(r); err != nil { + t.Fatalf("RoundTrip() returned %v, want no error", err) + } else if resp != want { + t.Fatalf("RoundTrip() = %v, want %v", resp, want) + } +} + +func TestGraphQLRoundTripper_BodyReadError(t *testing.T) { + want := errors.New("read failed") + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(iotest.ErrReader(want)), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); !errors.Is(err, want) { + t.Fatalf("RoundTrip() returned %v, want %v", err, want) + } +} + +func TestGraphQLRoundTripper_JSONUnmarshalError(t *testing.T) { + var want *json.SyntaxError + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader("{")), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); !errors.As(err, &want) { + t.Fatalf("RoundTrip() returned %v, want %v", err, want) + } +} + +func TestGraphQLRoundTripper_NoErrors(t *testing.T) { + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(`{"data":{}}`)), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); err != nil { + t.Fatalf("RoundTrip() returned %v, want no errors", err) + } +} + +func TestGraphQLRoundTripper_EmptyErrors(t *testing.T) { + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(`{"data":null, "errors":[]}`)), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); err != nil { + t.Fatalf("RoundTrip() returned %v, want no errors", err) + } +} + +func TestGraphQLRoundTripper_OneError(t *testing.T) { + var want *GraphQLErrors + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(`{"data":null, "errors":[{"message":"test", "type":"test"}]}`)), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); !errors.As(err, &want) { + t.Fatalf("RoundTrip() returned %v, want %v", err, want) + } + if n := len(want.Errors()); n != 1 { + t.Fatalf("len(Errors) = %d; want 1", n) + } +} + +func TestGraphQLRoundTripper_MultipleErrors(t *testing.T) { + var want *GraphQLErrors + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(`{"data":null, "errors":[{"message":"test", "type":"test"}, {"message": "test2", "type":"test"}]}`)), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); !errors.As(err, &want) { + t.Fatalf("RoundTrip() returned %v, want %v", err, want) + } + if n := len(want.Errors()); n != 2 { + t.Fatalf("len(Errors) = %d; want 2", n) + } +} + +func TestGraphQLRoundTripper_OneErrorNotFound(t *testing.T) { + want := ErrGraphQLNotFound + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(`{"data":null, "errors":[{"message":"test", "type":"NOT_FOUND"}]}`)), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + if _, err := rt.RoundTrip(r); !errors.Is(err, want) { + t.Fatalf("RoundTrip() returned %v, want %v", err, want) + } +} + +func TestGraphQLRoundTripper_MultipleErrors_OneNotFound(t *testing.T) { + var want *GraphQLErrors + rt := &graphQLRoundTripper{inner: testRoundTripperFunc(func(r *http.Request) (*http.Response, error) { + return &http.Response{ + StatusCode: http.StatusOK, + Body: io.NopCloser(strings.NewReader(`{"data":null, "errors":[{"message":"test", "type":"NOT_FOUND"}, {"message": "test2", "type":"test"}]}`)), + }, nil + })} + r, err := http.NewRequestWithContext(context.Background(), "GET", "http://example.com", strings.NewReader("")) + if err != nil { + t.Fatalf("NewRequest() failed with %v", err) + } + _, err = rt.RoundTrip(r) + if !errors.As(err, &want) { + t.Fatalf("RoundTrip() returned %v, want %v", err, want) + } + if errors.Is(err, ErrGraphQLNotFound) { + t.Fatalf("RoundTrip() returned %v is %v", err, ErrGraphQLNotFound) + } + if !want.HasType(gitHubGraphQLNotFoundType) { + t.Fatalf("HasType(%v) returned false, want true", gitHubGraphQLNotFoundType) + } +} diff --git a/cmd/collect_signals/result/csv.go b/internal/signalio/csv.go similarity index 77% rename from cmd/collect_signals/result/csv.go rename to internal/signalio/csv.go index 03d8d49d..494677d5 100644 --- a/cmd/collect_signals/result/csv.go +++ b/internal/signalio/csv.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package result +package signalio import ( "encoding/csv" @@ -44,18 +44,27 @@ func headerFromSignalSets(sets []signal.Set) []string { return hs } -func NewCsvWriter(w io.Writer, emptySets []signal.Set) Writer { +func CsvWriter(w io.Writer, emptySets []signal.Set) Writer { return &csvWriter{ header: headerFromSignalSets(emptySets), w: csv.NewWriter(w), } } -func (w *csvWriter) Record() RecordWriter { - return &csvRecord{ - values: make(map[string]string), - sink: w, +// WriteSignals implements the Writer interface. +func (w *csvWriter) WriteSignals(signals []signal.Set) error { + values := make(map[string]string) + for _, s := range signals { + // Get all of the signal data from the set and serialize it. + for k, v := range signal.SetAsMap(s, true) { + if s, err := marshalValue(v); err != nil { + return fmt.Errorf("failed to write field %s: %w", k, err) + } else { + values[k] = s + } + } } + return w.writeRecord(values) } func (w *csvWriter) maybeWriteHeader() error { @@ -75,13 +84,13 @@ func (w *csvWriter) maybeWriteHeader() error { return w.w.Write(w.header) } -func (w *csvWriter) writeRecord(c *csvRecord) error { +func (w *csvWriter) writeRecord(values map[string]string) error { if err := w.maybeWriteHeader(); err != nil { return err } var rec []string for _, k := range w.header { - rec = append(rec, c.values[k]) + rec = append(rec, values[k]) } // Grab the lock when we're ready to write the record to prevent // concurrent writes to w. @@ -94,27 +103,6 @@ func (w *csvWriter) writeRecord(c *csvRecord) error { return w.w.Error() } -type csvRecord struct { - values map[string]string - sink *csvWriter -} - -func (r *csvRecord) WriteSignalSet(s signal.Set) error { - data := signal.SetAsMap(s, true) - for k, v := range data { - if s, err := marshalValue(v); err != nil { - return fmt.Errorf("failed to write field %s: %w", k, err) - } else { - r.values[k] = s - } - } - return nil -} - -func (r *csvRecord) Done() error { - return r.sink.writeRecord(r) -} - func marshalValue(value any) (string, error) { switch v := value.(type) { case bool, int, int16, int32, int64, uint, uint16, uint32, uint64, byte, float32, float64, string: diff --git a/cmd/collect_signals/result/emitter.go b/internal/signalio/writer.go similarity index 67% rename from cmd/collect_signals/result/emitter.go rename to internal/signalio/writer.go index a39d77bf..556d9cec 100644 --- a/cmd/collect_signals/result/emitter.go +++ b/internal/signalio/writer.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package result +package signalio import ( "errors" @@ -22,16 +22,7 @@ import ( var ErrorMarshalFailure = errors.New("failed to marshal value") -type RecordWriter interface { - // WriteSignalSet is used to output the value for a signal.Set for a record. - WriteSignalSet(signal.Set) error - - // Done indicates that all the fields for the record have been written and - // record is complete. - Done() error -} - type Writer interface { - // Record returns a RecordWriter that can be used to write a new record. - Record() RecordWriter + // WriteSignals outputs the all the signals collector to storage. + WriteSignals([]signal.Set) error } From 82747b6d44e37b2fde457b3bad29c23be0ffc75f Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 28 Oct 2022 12:33:12 +1100 Subject: [PATCH 111/172] Refactor scoring so it can be done at signal collection time as well. (#224) * Move scoring logic into internal/scorer so it can be reused. * Make the score config file optional by embedding a default. * Add support for additional fields when writing signals. * Add scoring by default to the signal collector. Signed-off-by: Caleb Brown --- cmd/collect_signals/main.go | 105 ++++++++++++---- cmd/scorer/README.md | 2 +- cmd/scorer/main.go | 80 +++++-------- .../scorer/algorithm/algorithm.go | 0 .../scorer/algorithm/distribution.go | 0 {cmd => internal}/scorer/algorithm/input.go | 0 .../scorer/algorithm/registry.go | 0 {cmd => internal}/scorer/algorithm/value.go | 0 {cmd => internal}/scorer/algorithm/wam/wam.go | 2 +- {cmd => internal}/scorer/config.go | 4 +- internal/scorer/default.go | 35 ++++++ internal/scorer/default_config.yml | 79 ++++++++++++ internal/scorer/scorer.go | 112 ++++++++++++++++++ internal/signalio/csv.go | 17 ++- internal/signalio/writer.go | 8 +- 15 files changed, 363 insertions(+), 81 deletions(-) rename {cmd => internal}/scorer/algorithm/algorithm.go (100%) rename {cmd => internal}/scorer/algorithm/distribution.go (100%) rename {cmd => internal}/scorer/algorithm/input.go (100%) rename {cmd => internal}/scorer/algorithm/registry.go (100%) rename {cmd => internal}/scorer/algorithm/value.go (100%) rename {cmd => internal}/scorer/algorithm/wam/wam.go (95%) rename {cmd => internal}/scorer/config.go (97%) create mode 100644 internal/scorer/default.go create mode 100644 internal/scorer/default_config.yml create mode 100644 internal/scorer/scorer.go diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 82893a8a..76a1ed33 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -33,6 +33,7 @@ import ( "github.com/ossf/criticality_score/internal/infile" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/scorer" "github.com/ossf/criticality_score/internal/signalio" "github.com/ossf/criticality_score/internal/workerpool" ) @@ -40,12 +41,15 @@ import ( const defaultLogLevel = zapcore.InfoLevel var ( - gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") - depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") - depsdevDatasetFlag = flag.String("depsdev-dataset", collector.DefaultGCPDatasetName, "the BigQuery dataset name to use.") - workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") - logLevel = defaultLogLevel - logEnv log.Env + gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") + depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") + depsdevDatasetFlag = flag.String("depsdev-dataset", collector.DefaultGCPDatasetName, "the BigQuery dataset name to use.") + scoringDisableFlag = flag.Bool("scoring-disable", false, "disables the generation of scores.") + scoringConfigFlag = flag.String("scoring-config", "", "path to a YAML file for configuring the scoring algorithm.") + scoringColumnNameFlag = flag.String("scoring-column", "", "manually specify the name for the column used to hold the score.") + workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") + logLevel = defaultLogLevel + logEnv log.Env ) func init() { @@ -64,27 +68,47 @@ func init() { } } -func handleRepo(ctx context.Context, logger *zap.Logger, c *collector.Collector, u *url.URL, out signalio.Writer) { - ss, err := c.Collect(ctx, u) +func getScorer(logger *zap.Logger) *scorer.Scorer { + if *scoringDisableFlag { + logger.Info("Scoring disabled") + return nil + } + if *scoringConfigFlag == "" { + logger.Info("Preparing default scorer") + return scorer.FromDefaultConfig() + } + // Prepare the scorer from the config file + logger = logger.With( + zap.String("filename", *scoringConfigFlag), + ) + logger.Info("Preparing scorer from config") + cf, err := os.Open(*scoringConfigFlag) if err != nil { - if errors.Is(err, collector.ErrUncollectableRepo) { - logger.With( - zap.Error(err), - ).Warn("Repo cannot be collected") - return - } logger.With( zap.Error(err), - ).Error("Failed to collect signals for repo") - os.Exit(1) // TODO: pass up the error + ).Error("Failed to open scoring config file") + os.Exit(2) } + defer cf.Close() - if err := out.WriteSignals(ss); err != nil { + s, err := scorer.FromConfig(scorer.NameFromFilepath(*scoringConfigFlag), cf) + if err != nil { logger.With( zap.Error(err), - ).Error("Failed to write signal set") - os.Exit(1) // TODO: pass up the error + ).Error("Failed to initialize scorer") + os.Exit(2) } + return s +} + +func generateScoreColumnName(s *scorer.Scorer) string { + if s == nil { + return "" + } + if *scoringColumnNameFlag != "" { + return *scoringColumnNameFlag + } + return s.Name() } func main() { @@ -96,6 +120,10 @@ func main() { } defer logger.Sync() + // Prepare the scorer, if it is enabled. + s := getScorer(logger) + scoreColumnName := generateScoreColumnName(s) + // Complete the validation of args if flag.NArg() != 2 { logger.Error("Must have one input file and one output file specified.") @@ -150,14 +178,49 @@ func main() { defer w.Close() // Prepare the output writer - out := signalio.CsvWriter(w, c.EmptySets()) + extras := []string{} + if s != nil { + extras = append(extras, scoreColumnName) + } + out := signalio.CsvWriter(w, c.EmptySets(), extras...) // Start the workers that process a channel of repo urls. repos := make(chan *url.URL) wait := workerpool.WorkerPool(*workersFlag, func(worker int) { innerLogger := logger.With(zap.Int("worker", worker)) for u := range repos { - handleRepo(ctx, innerLogger.With(zap.String("url", u.String())), c, u, out) + l := innerLogger.With(zap.String("url", u.String())) + ss, err := c.Collect(ctx, u) + if err != nil { + if errors.Is(err, collector.ErrUncollectableRepo) { + l.With( + zap.Error(err), + ).Warn("Repo cannot be collected") + return + } + l.With( + zap.Error(err), + ).Error("Failed to collect signals for repo") + os.Exit(1) // TODO: pass up the error + } + + // If scoring is enabled, prepare the extra data to be output. + extras := []signalio.Field{} + if s != nil { + f := signalio.Field{ + Key: scoreColumnName, + Value: fmt.Sprintf("%.5f", s.Score(ss)), + } + extras = append(extras, f) + } + + // Write the signals to storage. + if err := out.WriteSignals(ss, extras...); err != nil { + l.With( + zap.Error(err), + ).Error("Failed to write signal set") + os.Exit(1) // TODO: pass up the error + } } }) diff --git a/cmd/scorer/README.md b/cmd/scorer/README.md index bc0a6dad..782d91fb 100644 --- a/cmd/scorer/README.md +++ b/cmd/scorer/README.md @@ -48,7 +48,7 @@ fail. #### Scoring flags - `-config string` the name of a YAML config file to use for calculating the - score. Required. + score. Defaults to the original set of weights and scores. - `-column string` the name of the column to store the score in. Defaults to the name of the config file with `_score` appended (e.g. `config.yml` becomes `config_score`). diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index 13882379..97a880d6 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -41,17 +41,14 @@ import ( "io" "os" "path" - "regexp" - "strconv" - "strings" "go.uber.org/zap" "go.uber.org/zap/zapcore" - _ "github.com/ossf/criticality_score/cmd/scorer/algorithm/wam" "github.com/ossf/criticality_score/internal/infile" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/scorer" ) const defaultLogLevel = zapcore.InfoLevel @@ -79,20 +76,12 @@ func init() { } } -func generateColumnName() string { +func generateColumnName(s *scorer.Scorer) string { if *columnNameFlag != "" { // If we have the column name, just use it as the name return *columnNameFlag } - // Get the name of the config file used, without the path - f := path.Base(*configFlag) - ext := path.Ext(f) - // Strip the extension and convert to lowercase - f = strings.ToLower(strings.TrimSuffix(f, ext)) - // Change any non-alphanumeric character into an underscore - f = regexp.MustCompile("[^a-z0-9_]").ReplaceAllString(f, "_") - // Append "_score" to the end - return f + "_score" + return s.Name() } func makeOutHeader(header []string, resultColumn string) ([]string, error) { @@ -104,15 +93,10 @@ func makeOutHeader(header []string, resultColumn string) ([]string, error) { return append(header, resultColumn), nil } -func makeRecord(header, row []string) map[string]float64 { - record := make(map[string]float64) +func makeRecord(header, row []string) map[string]string { + record := make(map[string]string) for i, k := range header { - raw := row[i] - v, err := strconv.ParseFloat(raw, 64) - if err != nil { - // Failed to parse raw into a float, ignore the field - continue - } + v := row[i] record[k] = v } return record @@ -160,35 +144,29 @@ func main() { w := csv.NewWriter(fw) defer w.Flush() - // Prepare the algorithm from the config file + var s *scorer.Scorer if *configFlag == "" { - logger.Error("Must have a config file set") - os.Exit(2) - } + s = scorer.FromDefaultConfig() + } else { + // Prepare the scorer from the config file + cf, err := os.Open(*configFlag) + if err != nil { + logger.With( + zap.Error(err), + zap.String("filename", *configFlag), + ).Error("Failed to open config file") + os.Exit(2) + } + defer cf.Close() - cf, err := os.Open(*configFlag) - if err != nil { - logger.With( - zap.Error(err), - zap.String("filename", *configFlag), - ).Error("Failed to open config file") - os.Exit(2) - } - c, err := LoadConfig(cf) - if err != nil { - logger.With( - zap.Error(err), - zap.String("filename", *configFlag), - ).Error("Failed to parse config file") - os.Exit(2) - } - a, err := c.Algorithm() - if err != nil { - logger.With( - zap.Error(err), - zap.String("algorithm", c.Name), - ).Error("Failed to get the algorithm") - os.Exit(2) + s, err = scorer.FromConfig(scorer.NameFromFilepath(*configFlag), cf) + if err != nil { + logger.With( + zap.Error(err), + zap.String("filename", *configFlag), + ).Error("Failed to initialize scorer") + os.Exit(2) + } } inHeader, err := r.Read() @@ -200,7 +178,7 @@ func main() { } // Generate and output the CSV header row - outHeader, err := makeOutHeader(inHeader, generateColumnName()) + outHeader, err := makeOutHeader(inHeader, generateColumnName(s)) if err != nil { logger.With( zap.Error(err), @@ -227,7 +205,7 @@ func main() { os.Exit(2) } record := makeRecord(inHeader, row) - score := a.Score(record) + score := s.ScoreRaw(record) row = append(row, fmt.Sprintf("%.5f", score)) pq.PushRow(row, score) } diff --git a/cmd/scorer/algorithm/algorithm.go b/internal/scorer/algorithm/algorithm.go similarity index 100% rename from cmd/scorer/algorithm/algorithm.go rename to internal/scorer/algorithm/algorithm.go diff --git a/cmd/scorer/algorithm/distribution.go b/internal/scorer/algorithm/distribution.go similarity index 100% rename from cmd/scorer/algorithm/distribution.go rename to internal/scorer/algorithm/distribution.go diff --git a/cmd/scorer/algorithm/input.go b/internal/scorer/algorithm/input.go similarity index 100% rename from cmd/scorer/algorithm/input.go rename to internal/scorer/algorithm/input.go diff --git a/cmd/scorer/algorithm/registry.go b/internal/scorer/algorithm/registry.go similarity index 100% rename from cmd/scorer/algorithm/registry.go rename to internal/scorer/algorithm/registry.go diff --git a/cmd/scorer/algorithm/value.go b/internal/scorer/algorithm/value.go similarity index 100% rename from cmd/scorer/algorithm/value.go rename to internal/scorer/algorithm/value.go diff --git a/cmd/scorer/algorithm/wam/wam.go b/internal/scorer/algorithm/wam/wam.go similarity index 95% rename from cmd/scorer/algorithm/wam/wam.go rename to internal/scorer/algorithm/wam/wam.go index a545e194..2149e064 100644 --- a/cmd/scorer/algorithm/wam/wam.go +++ b/internal/scorer/algorithm/wam/wam.go @@ -18,7 +18,7 @@ package wam import ( - "github.com/ossf/criticality_score/cmd/scorer/algorithm" + "github.com/ossf/criticality_score/internal/scorer/algorithm" ) type WeighetedArithmeticMean struct { diff --git a/cmd/scorer/config.go b/internal/scorer/config.go similarity index 97% rename from cmd/scorer/config.go rename to internal/scorer/config.go index fc5aa72a..bfd7ddcb 100644 --- a/cmd/scorer/config.go +++ b/internal/scorer/config.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package main +package scorer import ( "errors" @@ -21,7 +21,7 @@ import ( "gopkg.in/yaml.v3" - "github.com/ossf/criticality_score/cmd/scorer/algorithm" + "github.com/ossf/criticality_score/internal/scorer/algorithm" ) type Condition struct { diff --git a/internal/scorer/default.go b/internal/scorer/default.go new file mode 100644 index 00000000..5b7deb39 --- /dev/null +++ b/internal/scorer/default.go @@ -0,0 +1,35 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package scorer + +import ( + "bytes" + _ "embed" +) + +const defaultScoreName = "default_score" + +//go:generate cp ../../config/scorer/original_pike.yml default_config.yml +//go:embed default_config.yml +var defaultConfigContent []byte + +func FromDefaultConfig() *Scorer { + r := bytes.NewReader(defaultConfigContent) + s, err := FromConfig(defaultScoreName, r) + if err != nil { + panic(err) + } + return s +} diff --git a/internal/scorer/default_config.yml b/internal/scorer/default_config.yml new file mode 100644 index 00000000..f2a1563d --- /dev/null +++ b/internal/scorer/default_config.yml @@ -0,0 +1,79 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +# The original set of weights defined for the criticality score project using +# Rob Pike's algorithm as implemented in the original Python project. +algorithm: weighted_arithmetic_mean + +inputs: + - field: legacy.created_since + weight: 1 + bounds: + upper: 120 + distribution: zipfian + + - field: legacy.updated_since + weight: 1 + bounds: + upper: 120 + smaller_is_better: yes + distribution: zipfian + + - field: legacy.contributor_count + weight: 2 + bounds: + upper: 5000 + distribution: zipfian + + - field: legacy.org_count + weight: 1 + bounds: + upper: 10 + distribution: zipfian + + - field: legacy.commit_frequency + weight: 1 + bounds: + upper: 1000 + distribution: zipfian + + - field: legacy.recent_release_count + weight: 0.5 + bounds: + upper: 26 + distribution: zipfian + + - field: legacy.updated_issues_count + weight: 0.5 + bounds: + upper: 5000 + distribution: zipfian + + - field: legacy.closed_issues_count + weight: 0.5 + bounds: + upper: 5000 + distribution: zipfian + + - field: legacy.issue_comment_frequency + weight: 1 + bounds: + upper: 15 + distribution: zipfian + + - field: legacy.github_mention_count + weight: 2 + bounds: + upper: 500000 + distribution: zipfian diff --git a/internal/scorer/scorer.go b/internal/scorer/scorer.go new file mode 100644 index 00000000..0eaf4564 --- /dev/null +++ b/internal/scorer/scorer.go @@ -0,0 +1,112 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package scorer + +import ( + "fmt" + "io" + "path" + "regexp" + "strconv" + "strings" + + "github.com/ossf/criticality_score/internal/collector/signal" + "github.com/ossf/criticality_score/internal/scorer/algorithm" + _ "github.com/ossf/criticality_score/internal/scorer/algorithm/wam" +) + +type Scorer struct { + a algorithm.Algorithm + name string +} + +func FromConfig(name string, r io.Reader) (*Scorer, error) { + cfg, err := LoadConfig(r) + if err != nil { + return nil, fmt.Errorf("load config: %w", err) + } + a, err := cfg.Algorithm() + if err != nil { + return nil, fmt.Errorf("create algorithm: %w", err) + } + return &Scorer{ + name: name, + a: a, + }, nil +} + +func (s *Scorer) Score(signals []signal.Set) float64 { + record := make(map[string]float64) + for _, s := range signals { + // Get all of the signal data from the set and floatify it. + for k, v := range signal.SetAsMap(s, true) { + switch r := v.(type) { + case float64: + record[k] = r + case float32: + record[k] = float64(r) + case int: + record[k] = float64(r) + case int16: + record[k] = float64(r) + case int32: + record[k] = float64(r) + case int64: + record[k] = float64(r) + case uint: + record[k] = float64(r) + case uint16: + record[k] = float64(r) + case uint32: + record[k] = float64(r) + case uint64: + record[k] = float64(r) + case byte: + record[k] = float64(r) + } + } + } + return s.a.Score(record) +} + +func (s *Scorer) ScoreRaw(raw map[string]string) float64 { + record := make(map[string]float64) + for k, rawV := range raw { + // TODO: improve this behavior + v, err := strconv.ParseFloat(rawV, 64) + if err != nil { + // Failed to parse raw into a float, ignore the field + continue + } + record[k] = v + } + return s.a.Score(record) +} + +func (s *Scorer) Name() string { + return s.name +} + +func NameFromFilepath(filepath string) string { + // Get the name of the file used, without the path + f := path.Base(filepath) + ext := path.Ext(f) + // Strip the extension and convert to lowercase + f = strings.ToLower(strings.TrimSuffix(f, ext)) + // Change any non-alphanumeric character into an underscore + f = regexp.MustCompile("[^a-z0-9_]").ReplaceAllString(f, "_") + // Append "_score" to the end + return f + "_score" +} diff --git a/internal/signalio/csv.go b/internal/signalio/csv.go index 494677d5..cf1965ab 100644 --- a/internal/signalio/csv.go +++ b/internal/signalio/csv.go @@ -33,7 +33,7 @@ type csvWriter struct { mu sync.Mutex } -func headerFromSignalSets(sets []signal.Set) []string { +func headerFromSignalSets(sets []signal.Set, extra []string) []string { var hs []string for _, s := range sets { if err := signal.ValidateSet(s); err != nil { @@ -41,18 +41,20 @@ func headerFromSignalSets(sets []signal.Set) []string { } hs = append(hs, signal.SetFields(s, true)...) } + // Append all the extra fields + hs = append(hs, extra...) return hs } -func CsvWriter(w io.Writer, emptySets []signal.Set) Writer { +func CsvWriter(w io.Writer, emptySets []signal.Set, extra ...string) Writer { return &csvWriter{ - header: headerFromSignalSets(emptySets), + header: headerFromSignalSets(emptySets, extra), w: csv.NewWriter(w), } } // WriteSignals implements the Writer interface. -func (w *csvWriter) WriteSignals(signals []signal.Set) error { +func (w *csvWriter) WriteSignals(signals []signal.Set, extra ...Field) error { values := make(map[string]string) for _, s := range signals { // Get all of the signal data from the set and serialize it. @@ -64,6 +66,13 @@ func (w *csvWriter) WriteSignals(signals []signal.Set) error { } } } + for _, f := range extra { + if s, err := marshalValue(f.Value); err != nil { + return fmt.Errorf("failed to write field %s: %w", f.Key, err) + } else { + values[f.Key] = s + } + } return w.writeRecord(values) } diff --git a/internal/signalio/writer.go b/internal/signalio/writer.go index 556d9cec..32376d6e 100644 --- a/internal/signalio/writer.go +++ b/internal/signalio/writer.go @@ -22,7 +22,13 @@ import ( var ErrorMarshalFailure = errors.New("failed to marshal value") +//nolint:govet +type Field struct { + Key string + Value any +} + type Writer interface { // WriteSignals outputs the all the signals collector to storage. - WriteSignals([]signal.Set) error + WriteSignals([]signal.Set, ...Field) error } From aa3935b75baf7288d34b2bcb078c57db252e2f3b Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 28 Oct 2022 17:01:09 +1100 Subject: [PATCH 112/172] Clone new binary criticality_score from collect_signals. (#226) * Copy cmd/collect_signals/... to cmd/criticality_score/... * Fix references to collect_signals in criticality_score docs. * Remove internal parallelism from collect_signals. * Remove worker flag from README as well. * More readme updates to better communicate the changes. Signed-off-by: Caleb Brown --- cmd/collect_signals/README.md | 208 +------------------------ cmd/collect_signals/main.go | 90 +++++------ cmd/criticality_score/README.md | 206 +++++++++++++++++++++++++ cmd/criticality_score/main.go | 260 ++++++++++++++++++++++++++++++++ cmd/enumerate_github/README.md | 3 +- 5 files changed, 506 insertions(+), 261 deletions(-) create mode 100644 cmd/criticality_score/README.md create mode 100644 cmd/criticality_score/main.go diff --git a/cmd/collect_signals/README.md b/cmd/collect_signals/README.md index fca33115..cfe357e7 100644 --- a/cmd/collect_signals/README.md +++ b/cmd/collect_signals/README.md @@ -1,209 +1,5 @@ # Signal Collector This tool is used to collect signal data for a set of project repositories for -generating a criticality score. - -The input of this tool could by the output of the `enumerate_github` tool. - -The output of this tool is used as an input for the `scorer` tool, or for input -into a data analysis system such as BigQuery. - -## Example - -```shell -$ export GITHUB_TOKEN=ghp_x # Personal Access Token Goes Here -$ gcloud login --update-adc # Sign-in to GCP -$ collect_signals \ - -workers=1 \ - github_projects.txt \ - signals.csv -``` - -## Install - -```shell -$ go install github.com/ossf/criticality_score/cmd/collect_signals -``` - -## Usage - -```shell -$ collect_signals [FLAGS]... IN_FILE OUT_FILE -``` - -Project repository URLs are read from the specified `IN_FILE`. If `-` is passed -in as an `IN_FILE` URLs will read from STDIN. - -Results are written in CSV format to `OUT_FILE`. If `OUT_FILE` is `-` the -results will be written to STDOUT. - -`FLAGS` are optional. See below for documentation. - -### Authentication - -`collect_signals` requires authentication to GitHub, and optionally Google Cloud Platform to run. - -#### GitHub Authentication - -A comma delimited environment variable with one or more GitHub Personal Access -Tokens must be set - -Supported environment variables are `GITHUB_AUTH_TOKEN`, `GITHUB_TOKEN`, -`GH_TOKEN`, or `GH_AUTH_TOKEN`. - -Example: - -```shell -$ export GITHUB_TOKEN=ghp_abc,ghp_123 -``` - -#### GCP Authentication - -BigQuery access requires the "BigQuery User" (`roles/bigquery.user`) role added -to the account used, or be an "Owner". - -##### Option 1: `gcloud login` - -This option is useful during development. Run `gcloud login --update-adc` to -login to GCP and prepare application default credentials. - -##### Option 2: GCE Service Worker - -If running on a GCE instance a service worker will be associated with the -machine. - -Simply ensure the service worker is added to the "BigQuery User" role. - -##### Option 3: Custom Service Worker - -A custom service worker is ideal for limiting access to GCP resources. - -One can be created through the console or via `gcloud` on the command line. - -For example: - -```shell -$ # Create the service worker account -$ gcloud iam service-accounts create [SERVICE-ACCOUNT-ID] -$ # Add the service worker to the "BigQuery User" role -$ gcloud projects add-iam-policy-binding [PROJECT-ID] --member="serviceAccount:[SERVICE-ACCOUNT-ID]@[PROJECT-ID].iam.gserviceaccount.com" --role=roles/bigquery.user -$ # Generate a credentials file for the service worker -$ gcloud iam service-accounts keys create [FILENAME].json --iam-account=[SERVICE-ACCOUNT-ID@[PROJECT-ID].iam.gserviceaccount.com -``` - -To use the service worker account the json credential file needs to be passed -in through the `GOOGLE_APPLICATION_CREDENTIALS` environment variable. - -Example: - -```shell -$ export GOOGLE_APPLICATION_CREDENTIALS=[FILENAME].json -``` - -See more on GCP -[service account docs](https://cloud.google.com/iam/docs/creating-managing-service-accounts). - -### Flags - -#### Output flags - -- `-append` appends output to `FILE` if it already exists. -- `-force` overwrites `FILE` if it already exists and `-append` is not set. - -If `FILE` exists and neither `-append` nor `-force` is set the command will fail. - -#### Google Cloud Platform flags - -- `-gcp-project-id string` the Google Cloud Project ID to use. Auto-detects by default. - -#### deps.dev Collection Flags - -- `-depsdev-disable` disables the collection of signals from deps.dev. -- `-depsdev-dataset string` the BigQuery dataset name to use. Default is `depsdev_analysis`. - -#### Misc flags - -- `-log level` set the level of logging. Can be `debug`, `info` (default), `warn` or `error`. -- `-workers int` the total number of concurrent workers to use. Default is `1`. -- `-help` displays help text. - -## Q&A - -### Q: How long does it take? - -It takes ~2.5 seconds per repository on a fast computer with excellent internet -access. - -From experience, if no rate limits are hit, a single worker can collect about -1400 repositories in an hour. - -### Q: How many workers should I use? - -Generally, use 1 worker per one or two Personal Access Tokens. - -On a fast computer with excellent internet access, a single worker can consume -the quota for a single token in about 30-40 minutes. - -### Q: Any tips on making it run fast and reliable? - -1. Spin up a compute instance in GCE with lots of RAM and fast network: - - Uses GCP's fast/reliable internet connectivity. - - Reduces latency and costs for querying BigQuery data (and perhaps - GitHub's data too). - - Prevents downtime due to local IT failures. -1. Shard the input repository list and run multiple instances on different - hosts with different GitHub tokens: - - Ensures work progresses even if one instance stops. - - Provides additional compute and network resources. - -### Q: How do I restart after a failure? - -If running with a single worker this process is fairly straightforward. - -1. Copy the input repository list file to a new file to edit. -1. Open the new file in an editor (note: it may be very large). -1. `tail -25` the output csv file to view the last entries. -1. In the editor, find the entry that corresponds to the last csv entry. - - If running with a single worker: delete this repository url and *all* - repository urls above it. - - If running with multiple workers: manually delete repository urls that - correspond to entries in the output csv until there are no unprocessed - repository urls interleaving processed urls. Delete the remaining urls - above the unprocessed urls. -1. Restart `collect_signals`: - - Use the new file as the input. - - Either use a new file as the output, or specify `-append`. - -*Note:* when correlating URLs it is possible that the repository has been -renamed. - -### Q: How much will GCP usage cost? - -deps.dev support is designed to work within the free pricing tier for GCP. - -A single BigQuery query of 3Gb data is executed once, with the resulting table -used for subsequent queries. - -Network transit costs should be small enough to also sit within the free tier. - -A free GCE instance could be used to reduce network transit costs, but may slow -down the collection. - -## Development - -Rather than installing the binary, use `go run` to run the command. - -For example: - -```shell -$ go run ./cmd/collect_signals [FLAGS]... IN_FILE... OUT_FILE -``` - -Pass in a single repo using echo to quickly test signal collection, for example: - -```shell -$ echo "https://github.com/django/django" | \ - go run ./cmd/collect_signals \ - -log=debug \ - - - -``` \ No newline at end of file +generating a criticality score. It is intended to be used as part of a pool of +workers collecting signals for hundreds of thousands of repositories. diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 76a1ed33..e44bed6c 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -35,7 +35,6 @@ import ( "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/scorer" "github.com/ossf/criticality_score/internal/signalio" - "github.com/ossf/criticality_score/internal/workerpool" ) const defaultLogLevel = zapcore.InfoLevel @@ -47,7 +46,6 @@ var ( scoringDisableFlag = flag.Bool("scoring-disable", false, "disables the generation of scores.") scoringConfigFlag = flag.String("scoring-config", "", "path to a YAML file for configuring the scoring algorithm.") scoringColumnNameFlag = flag.String("scoring-column", "", "manually specify the name for the column used to hold the score.") - workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") logLevel = defaultLogLevel logEnv log.Env ) @@ -133,7 +131,7 @@ func main() { ctx := context.Background() // Bump the # idle conns per host - http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = *workersFlag * 5 + http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 5 opts := []collector.Option{ collector.EnableAllSources(), @@ -184,47 +182,7 @@ func main() { } out := signalio.CsvWriter(w, c.EmptySets(), extras...) - // Start the workers that process a channel of repo urls. - repos := make(chan *url.URL) - wait := workerpool.WorkerPool(*workersFlag, func(worker int) { - innerLogger := logger.With(zap.Int("worker", worker)) - for u := range repos { - l := innerLogger.With(zap.String("url", u.String())) - ss, err := c.Collect(ctx, u) - if err != nil { - if errors.Is(err, collector.ErrUncollectableRepo) { - l.With( - zap.Error(err), - ).Warn("Repo cannot be collected") - return - } - l.With( - zap.Error(err), - ).Error("Failed to collect signals for repo") - os.Exit(1) // TODO: pass up the error - } - - // If scoring is enabled, prepare the extra data to be output. - extras := []signalio.Field{} - if s != nil { - f := signalio.Field{ - Key: scoreColumnName, - Value: fmt.Sprintf("%.5f", s.Score(ss)), - } - extras = append(extras, f) - } - - // Write the signals to storage. - if err := out.WriteSignals(ss, extras...); err != nil { - l.With( - zap.Error(err), - ).Error("Failed to write signal set") - os.Exit(1) // TODO: pass up the error - } - } - }) - - // Read in each line from the input files + // Read in each line from the input files and process the urls scanner := bufio.NewScanner(r) for scanner.Scan() { line := scanner.Text() @@ -237,12 +195,41 @@ func main() { ).Error("Failed to parse project url") os.Exit(1) // TODO: add a flag to continue or abort on failure } - logger.With( - zap.String("url", u.String()), - ).Debug("Parsed project url") - // Send the url to the workers - repos <- u + l := logger.With(zap.String("url", u.String())) + l.Debug("Parsed project url") + + ss, err := c.Collect(ctx, u) + if err != nil { + if errors.Is(err, collector.ErrUncollectableRepo) { + l.With( + zap.Error(err), + ).Warn("Repo cannot be collected") + return + } + l.With( + zap.Error(err), + ).Error("Failed to collect signals for repo") + os.Exit(1) // TODO: pass up the error + } + + // If scoring is enabled, prepare the extra data to be output. + extras := []signalio.Field{} + if s != nil { + f := signalio.Field{ + Key: scoreColumnName, + Value: fmt.Sprintf("%.5f", s.Score(ss)), + } + extras = append(extras, f) + } + + // Write the signals to storage. + if err := out.WriteSignals(ss, extras...); err != nil { + l.With( + zap.Error(err), + ).Error("Failed to write signal set") + os.Exit(1) // TODO: pass up the error + } } if err := scanner.Err(); err != nil { logger.With( @@ -250,11 +237,6 @@ func main() { ).Error("Failed while reading input") os.Exit(2) } - // Close the repos channel to indicate that there is no more input. - close(repos) - - // Wait until all the workers have finished. - wait() // TODO: track metrics as we are running to measure coverage of data } diff --git a/cmd/criticality_score/README.md b/cmd/criticality_score/README.md new file mode 100644 index 00000000..2447d73d --- /dev/null +++ b/cmd/criticality_score/README.md @@ -0,0 +1,206 @@ +# Criticality Score tool + +This tool is used to collect signal data for one or more project repositories +and generates a criticality score. + +The input of this tool could by the output of the `enumerate_github` tool. + +## Example + +```shell +$ export GITHUB_TOKEN=ghp_x # Personal Access Token Goes Here +$ gcloud login --update-adc # Sign-in to GCP +$ criticality_score \ + -workers=1 \ + github_projects.txt \ + signals.csv +``` + +## Install + +```shell +$ go install github.com/ossf/criticality_score/cmd/criticality_score +``` + +## Usage + +```shell +$ criticality_score [FLAGS]... IN_FILE OUT_FILE +``` + +Project repository URLs are read from the specified `IN_FILE`. If `-` is passed +in as an `IN_FILE` URLs will read from STDIN. + +Results are written in CSV format to `OUT_FILE`. If `OUT_FILE` is `-` the +results will be written to STDOUT. + +`FLAGS` are optional. See below for documentation. + +### Authentication + +`criticality_score` requires authentication to GitHub, and optionally Google Cloud Platform to run. + +#### GitHub Authentication + +A comma delimited environment variable with one or more GitHub Personal Access +Tokens must be set + +Supported environment variables are `GITHUB_AUTH_TOKEN`, `GITHUB_TOKEN`, +`GH_TOKEN`, or `GH_AUTH_TOKEN`. + +Example: + +```shell +$ export GITHUB_TOKEN=ghp_abc,ghp_123 +``` + +#### GCP Authentication + +BigQuery access requires the "BigQuery User" (`roles/bigquery.user`) role added +to the account used, or be an "Owner". + +##### Option 1: `gcloud login` + +This option is useful during development. Run `gcloud login --update-adc` to +login to GCP and prepare application default credentials. + +##### Option 2: GCE Service Worker + +If running on a GCE instance a service worker will be associated with the +machine. + +Simply ensure the service worker is added to the "BigQuery User" role. + +##### Option 3: Custom Service Worker + +A custom service worker is ideal for limiting access to GCP resources. + +One can be created through the console or via `gcloud` on the command line. + +For example: + +```shell +$ # Create the service worker account +$ gcloud iam service-accounts create [SERVICE-ACCOUNT-ID] +$ # Add the service worker to the "BigQuery User" role +$ gcloud projects add-iam-policy-binding [PROJECT-ID] --member="serviceAccount:[SERVICE-ACCOUNT-ID]@[PROJECT-ID].iam.gserviceaccount.com" --role=roles/bigquery.user +$ # Generate a credentials file for the service worker +$ gcloud iam service-accounts keys create [FILENAME].json --iam-account=[SERVICE-ACCOUNT-ID@[PROJECT-ID].iam.gserviceaccount.com +``` + +To use the service worker account the json credential file needs to be passed +in through the `GOOGLE_APPLICATION_CREDENTIALS` environment variable. + +Example: + +```shell +$ export GOOGLE_APPLICATION_CREDENTIALS=[FILENAME].json +``` + +See more on GCP +[service account docs](https://cloud.google.com/iam/docs/creating-managing-service-accounts). + +### Flags + +#### Output flags + +- `-append` appends output to `FILE` if it already exists. +- `-force` overwrites `FILE` if it already exists and `-append` is not set. + +If `FILE` exists and neither `-append` nor `-force` is set the command will fail. + +#### Google Cloud Platform flags + +- `-gcp-project-id string` the Google Cloud Project ID to use. Auto-detects by default. + +#### deps.dev Collection Flags + +- `-depsdev-disable` disables the collection of signals from deps.dev. +- `-depsdev-dataset string` the BigQuery dataset name to use. Default is `depsdev_analysis`. + +#### Misc flags + +- `-log level` set the level of logging. Can be `debug`, `info` (default), `warn` or `error`. +- `-workers int` the total number of concurrent workers to use. Default is `1`. +- `-help` displays help text. + +## Q&A + +### Q: How long does it take? + +It takes ~2.5 seconds per repository on a fast computer with excellent internet +access. + +From experience, if no rate limits are hit, a single worker can collect about +1400 repositories in an hour. + +### Q: How many workers should I use? + +Generally, use 1 worker per one or two Personal Access Tokens. + +On a fast computer with excellent internet access, a single worker can consume +the quota for a single token in about 30-40 minutes. + +### Q: Any tips on making it run fast and reliable? + +1. Spin up a compute instance in GCE with lots of RAM and fast network: + - Uses GCP's fast/reliable internet connectivity. + - Reduces latency and costs for querying BigQuery data (and perhaps + GitHub's data too). + - Prevents downtime due to local IT failures. +1. Shard the input repository list and run multiple instances on different + hosts with different GitHub tokens: + - Ensures work progresses even if one instance stops. + - Provides additional compute and network resources. + +### Q: How do I restart after a failure? + +If running with a single worker this process is fairly straightforward. + +1. Copy the input repository list file to a new file to edit. +1. Open the new file in an editor (note: it may be very large). +1. `tail -25` the output csv file to view the last entries. +1. In the editor, find the entry that corresponds to the last csv entry. + - If running with a single worker: delete this repository url and *all* + repository urls above it. + - If running with multiple workers: manually delete repository urls that + correspond to entries in the output csv until there are no unprocessed + repository urls interleaving processed urls. Delete the remaining urls + above the unprocessed urls. +1. Restart `criticality_score`: + - Use the new file as the input. + - Either use a new file as the output, or specify `-append`. + +*Note:* when correlating URLs it is possible that the repository has been +renamed. + +### Q: How much will GCP usage cost? + +deps.dev support is designed to work within the free pricing tier for GCP. + +A single BigQuery query of 3Gb data is executed once, with the resulting table +used for subsequent queries. + +Network transit costs should be small enough to also sit within the free tier. + +A free GCE instance could be used to reduce network transit costs, but may slow +down the collection. + +## Development + +Rather than installing the binary, use `go run` to run the command. + +For example: + +```shell +$ go run ./cmd/criticality_score [FLAGS]... IN_FILE... OUT_FILE +``` + +Pass in a single repo using echo to quickly test signal collection, for example: + +```shell +$ echo "https://github.com/django/django" | \ + go run ./cmd/criticality_score \ + -log=debug \ + - - +``` \ No newline at end of file diff --git a/cmd/criticality_score/main.go b/cmd/criticality_score/main.go new file mode 100644 index 00000000..76a1ed33 --- /dev/null +++ b/cmd/criticality_score/main.go @@ -0,0 +1,260 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package main + +import ( + "bufio" + "context" + "errors" + "flag" + "fmt" + "net/http" + "net/url" + "os" + "path" + "strings" + + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + + "github.com/ossf/criticality_score/internal/collector" + "github.com/ossf/criticality_score/internal/infile" + log "github.com/ossf/criticality_score/internal/log" + "github.com/ossf/criticality_score/internal/outfile" + "github.com/ossf/criticality_score/internal/scorer" + "github.com/ossf/criticality_score/internal/signalio" + "github.com/ossf/criticality_score/internal/workerpool" +) + +const defaultLogLevel = zapcore.InfoLevel + +var ( + gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") + depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") + depsdevDatasetFlag = flag.String("depsdev-dataset", collector.DefaultGCPDatasetName, "the BigQuery dataset name to use.") + scoringDisableFlag = flag.Bool("scoring-disable", false, "disables the generation of scores.") + scoringConfigFlag = flag.String("scoring-config", "", "path to a YAML file for configuring the scoring algorithm.") + scoringColumnNameFlag = flag.String("scoring-column", "", "manually specify the name for the column used to hold the score.") + workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") + logLevel = defaultLogLevel + logEnv log.Env +) + +func init() { + flag.Var(&logLevel, "log", "set the `level` of logging.") + flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") + outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") + flag.Usage = func() { + cmdName := path.Base(os.Args[0]) + w := flag.CommandLine.Output() + fmt.Fprintf(w, "Usage:\n %s [FLAGS]... IN_FILE OUT_FILE\n\n", cmdName) + fmt.Fprintf(w, "Collects signals for each project repository listed.\n") + fmt.Fprintf(w, "IN_FILE must be either a file or - to read from stdin.\n") + fmt.Fprintf(w, "OUT_FILE must be either be a file or - to write to stdout.\n") + fmt.Fprintf(w, "\nFlags:\n") + flag.PrintDefaults() + } +} + +func getScorer(logger *zap.Logger) *scorer.Scorer { + if *scoringDisableFlag { + logger.Info("Scoring disabled") + return nil + } + if *scoringConfigFlag == "" { + logger.Info("Preparing default scorer") + return scorer.FromDefaultConfig() + } + // Prepare the scorer from the config file + logger = logger.With( + zap.String("filename", *scoringConfigFlag), + ) + logger.Info("Preparing scorer from config") + cf, err := os.Open(*scoringConfigFlag) + if err != nil { + logger.With( + zap.Error(err), + ).Error("Failed to open scoring config file") + os.Exit(2) + } + defer cf.Close() + + s, err := scorer.FromConfig(scorer.NameFromFilepath(*scoringConfigFlag), cf) + if err != nil { + logger.With( + zap.Error(err), + ).Error("Failed to initialize scorer") + os.Exit(2) + } + return s +} + +func generateScoreColumnName(s *scorer.Scorer) string { + if s == nil { + return "" + } + if *scoringColumnNameFlag != "" { + return *scoringColumnNameFlag + } + return s.Name() +} + +func main() { + flag.Parse() + + logger, err := log.NewLogger(logEnv, logLevel) + if err != nil { + panic(err) + } + defer logger.Sync() + + // Prepare the scorer, if it is enabled. + s := getScorer(logger) + scoreColumnName := generateScoreColumnName(s) + + // Complete the validation of args + if flag.NArg() != 2 { + logger.Error("Must have one input file and one output file specified.") + os.Exit(2) + } + + ctx := context.Background() + + // Bump the # idle conns per host + http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = *workersFlag * 5 + + opts := []collector.Option{ + collector.EnableAllSources(), + collector.GCPProject(*gcpProjectFlag), + collector.GCPDatasetName(*depsdevDatasetFlag), + } + if *depsdevDisableFlag { + opts = append(opts, collector.DisableSource(collector.SourceTypeDepsDev)) + } + + c, err := collector.New(ctx, logger, opts...) + if err != nil { + logger.With( + zap.Error(err), + ).Error("Failed to create collector") + os.Exit(2) + } + + inFilename := flag.Args()[0] + outFilename := flag.Args()[1] + + // Open the in-file for reading + r, err := infile.Open(context.Background(), inFilename) + if err != nil { + logger.With( + zap.String("filename", inFilename), + zap.Error(err), + ).Error("Failed to open an input file") + os.Exit(2) + } + defer r.Close() + + // Open the out-file for writing + w, err := outfile.Open(context.Background(), outFilename) + if err != nil { + logger.With( + zap.String("filename", outFilename), + zap.Error(err), + ).Error("Failed to open file for output") + os.Exit(2) + } + defer w.Close() + + // Prepare the output writer + extras := []string{} + if s != nil { + extras = append(extras, scoreColumnName) + } + out := signalio.CsvWriter(w, c.EmptySets(), extras...) + + // Start the workers that process a channel of repo urls. + repos := make(chan *url.URL) + wait := workerpool.WorkerPool(*workersFlag, func(worker int) { + innerLogger := logger.With(zap.Int("worker", worker)) + for u := range repos { + l := innerLogger.With(zap.String("url", u.String())) + ss, err := c.Collect(ctx, u) + if err != nil { + if errors.Is(err, collector.ErrUncollectableRepo) { + l.With( + zap.Error(err), + ).Warn("Repo cannot be collected") + return + } + l.With( + zap.Error(err), + ).Error("Failed to collect signals for repo") + os.Exit(1) // TODO: pass up the error + } + + // If scoring is enabled, prepare the extra data to be output. + extras := []signalio.Field{} + if s != nil { + f := signalio.Field{ + Key: scoreColumnName, + Value: fmt.Sprintf("%.5f", s.Score(ss)), + } + extras = append(extras, f) + } + + // Write the signals to storage. + if err := out.WriteSignals(ss, extras...); err != nil { + l.With( + zap.Error(err), + ).Error("Failed to write signal set") + os.Exit(1) // TODO: pass up the error + } + } + }) + + // Read in each line from the input files + scanner := bufio.NewScanner(r) + for scanner.Scan() { + line := scanner.Text() + + u, err := url.Parse(strings.TrimSpace(line)) + if err != nil { + logger.With( + zap.String("url", line), + zap.Error(err), + ).Error("Failed to parse project url") + os.Exit(1) // TODO: add a flag to continue or abort on failure + } + logger.With( + zap.String("url", u.String()), + ).Debug("Parsed project url") + + // Send the url to the workers + repos <- u + } + if err := scanner.Err(); err != nil { + logger.With( + zap.Error(err), + ).Error("Failed while reading input") + os.Exit(2) + } + // Close the repos channel to indicate that there is no more input. + close(repos) + + // Wait until all the workers have finished. + wait() + + // TODO: track metrics as we are running to measure coverage of data +} diff --git a/cmd/enumerate_github/README.md b/cmd/enumerate_github/README.md index 953fed80..0c200f2d 100644 --- a/cmd/enumerate_github/README.md +++ b/cmd/enumerate_github/README.md @@ -2,7 +2,8 @@ This tool is used to reliably enumerate projects on GitHub. -The output of this tool is used as an input for the `collect_signals` tool. +The output of this tool is can be used as an input for the `criticality_score` +tool, or for input for the `collect_signals` worker. ## Example From 22b763b8e5c99b8d10c99af6ccbede64f9a0e409 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 21:24:09 +1100 Subject: [PATCH 113/172] Bump ossf/scorecard-action from 2.0.3 to 2.0.6 (#219) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.0.3 to 2.0.6. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/865b4092859256271290c77adbd10a43f4779972...99c53751e09b9529366343771cc321ec74e9bd3d) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Caleb Brown --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index cc2bd5ad..e6c8054d 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -21,7 +21,7 @@ jobs: - name: "Checkout code" uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: "Run analysis" - uses: ossf/scorecard-action@865b4092859256271290c77adbd10a43f4779972 # v2.0.0-alpha.2 + uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # v2.0.0-alpha.2 with: results_file: results.sarif results_format: sarif From 3b9d6ad0a807cc1647ebd6a048f6522d49b6dab3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 21:41:49 +1100 Subject: [PATCH 114/172] Bump actions/upload-artifact from 3.1.0 to 3.1.1 (#222) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.0 to 3.1.1. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/3cea5372237819ed00197afe530f5a7ea3e805c8...83fd05a356d7e2593de66fc9913b3002723633cb) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index e6c8054d..d7c96d5b 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -34,7 +34,7 @@ jobs: # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts # Optional. - name: "Upload artifact" - uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v2 + uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v2 with: name: SARIF file path: results.sarif From fa10207779d61f91bf1dbfe2bc48dc37f1ce04e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 22:04:37 +1100 Subject: [PATCH 115/172] Bump actions/setup-go from 3.3.0 to 3.3.1 (#217) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3.3.0 to 3.3.1. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/268d8c0ca0432bb2cf416faae41297df9d262d7f...c4a742cab115ed795e34d4513e2cf7d472deb55f) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 468369cf..0cecf68f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f + - uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f with: go-version: 1.19 - name: Run tests @@ -22,7 +22,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - - uses: actions/setup-go@268d8c0ca0432bb2cf416faae41297df9d262d7f + - uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f with: go-version: 1.19 - name: golangci-lint From 98cf5497ba38106ef8edf4e8a5a2f99bf795f31c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 31 Oct 2022 22:11:25 +1100 Subject: [PATCH 116/172] Bump golangci/golangci-lint-action from 3.2.0 to 3.3.0 (#221) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.2.0 to 3.3.0. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/537aa1903e5d359d0b27dbc19ddd22c5087f3fbc...07db5389c99593f11ad7b44463c2d4233066a9b1) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0cecf68f..5e3be560 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -26,4 +26,4 @@ jobs: with: go-version: 1.19 - name: golangci-lint - uses: golangci/golangci-lint-action@537aa1903e5d359d0b27dbc19ddd22c5087f3fbc + uses: golangci/golangci-lint-action@07db5389c99593f11ad7b44463c2d4233066a9b1 From 219893c5deff42bb8f582942d2be8114ccbf4a21 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 4 Nov 2022 10:50:16 +1100 Subject: [PATCH 117/172] Make the output file an explicit flag, rather than a positional arg (#228) Moves the output file to an explicit -out arg. This moves criticality_score to a simpler CLI interface and supports the Python deprecation. All the binaries were updated to remain consistent. Signed-off-by: Caleb Brown --- cmd/collect_signals/main.go | 10 ++-- cmd/criticality_score/README.md | 15 +++--- cmd/criticality_score/main.go | 10 ++-- cmd/enumerate_github/README.md | 17 +++--- cmd/enumerate_github/main.go | 44 +++++++--------- cmd/scorer/README.md | 15 +++--- cmd/scorer/main.go | 10 ++-- go.work.sum | 7 +-- infra/k8s/enumerate_github.yaml | 3 +- infra/test/docker-compose.yml | 2 +- internal/outfile/outfile.go | 88 ++++++++++++++++++++++---------- internal/outfile/outfile_test.go | 68 ++++++++++++++++-------- 12 files changed, 169 insertions(+), 120 deletions(-) diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index e44bed6c..afe8bc8d 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -53,7 +53,7 @@ var ( func init() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") - outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") + outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "OUT_FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) w := flag.CommandLine.Output() @@ -123,8 +123,8 @@ func main() { scoreColumnName := generateScoreColumnName(s) // Complete the validation of args - if flag.NArg() != 2 { - logger.Error("Must have one input file and one output file specified.") + if flag.NArg() != 1 { + logger.Error("Must have an input file specified.") os.Exit(2) } @@ -151,7 +151,6 @@ func main() { } inFilename := flag.Args()[0] - outFilename := flag.Args()[1] // Open the in-file for reading r, err := infile.Open(context.Background(), inFilename) @@ -165,10 +164,9 @@ func main() { defer r.Close() // Open the out-file for writing - w, err := outfile.Open(context.Background(), outFilename) + w, err := outfile.Open(context.Background()) if err != nil { logger.With( - zap.String("filename", outFilename), zap.Error(err), ).Error("Failed to open file for output") os.Exit(2) diff --git a/cmd/criticality_score/README.md b/cmd/criticality_score/README.md index 2447d73d..7e3270d4 100644 --- a/cmd/criticality_score/README.md +++ b/cmd/criticality_score/README.md @@ -12,8 +12,8 @@ $ export GITHUB_TOKEN=ghp_x # Personal Access Token Goes Here $ gcloud login --update-adc # Sign-in to GCP $ criticality_score \ -workers=1 \ - github_projects.txt \ - signals.csv + -out=signals.csv \ + github_projects.txt ``` ## Install @@ -25,14 +25,14 @@ $ go install github.com/ossf/criticality_score/cmd/criticality_score ## Usage ```shell -$ criticality_score [FLAGS]... IN_FILE OUT_FILE +$ criticality_score [FLAGS]... IN_FILE ``` Project repository URLs are read from the specified `IN_FILE`. If `-` is passed in as an `IN_FILE` URLs will read from STDIN. -Results are written in CSV format to `OUT_FILE`. If `OUT_FILE` is `-` the -results will be written to STDOUT. +Results are written in CSV format to the output. By default `stdout` is used for +output. `FLAGS` are optional. See below for documentation. @@ -104,6 +104,7 @@ See more on GCP #### Output flags +- `-out FILE` specify the `FILE` to use for output. By default `stdout` is used. - `-append` appends output to `FILE` if it already exists. - `-force` overwrites `FILE` if it already exists and `-append` is not set. @@ -193,7 +194,7 @@ Rather than installing the binary, use `go run` to run the command. For example: ```shell -$ go run ./cmd/criticality_score [FLAGS]... IN_FILE... OUT_FILE +$ go run ./cmd/criticality_score [FLAGS]... IN_FILE... ``` Pass in a single repo using echo to quickly test signal collection, for example: @@ -202,5 +203,5 @@ Pass in a single repo using echo to quickly test signal collection, for example: $ echo "https://github.com/django/django" | \ go run ./cmd/criticality_score \ -log=debug \ - - - + - ``` \ No newline at end of file diff --git a/cmd/criticality_score/main.go b/cmd/criticality_score/main.go index 76a1ed33..4f971e0d 100644 --- a/cmd/criticality_score/main.go +++ b/cmd/criticality_score/main.go @@ -55,7 +55,7 @@ var ( func init() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") - outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") + outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) w := flag.CommandLine.Output() @@ -125,8 +125,8 @@ func main() { scoreColumnName := generateScoreColumnName(s) // Complete the validation of args - if flag.NArg() != 2 { - logger.Error("Must have one input file and one output file specified.") + if flag.NArg() != 1 { + logger.Error("Must have an input file specified.") os.Exit(2) } @@ -153,7 +153,6 @@ func main() { } inFilename := flag.Args()[0] - outFilename := flag.Args()[1] // Open the in-file for reading r, err := infile.Open(context.Background(), inFilename) @@ -167,10 +166,9 @@ func main() { defer r.Close() // Open the out-file for writing - w, err := outfile.Open(context.Background(), outFilename) + w, err := outfile.Open(context.Background()) if err != nil { logger.With( - zap.String("filename", outFilename), zap.Error(err), ).Error("Failed to open file for output") os.Exit(2) diff --git a/cmd/enumerate_github/README.md b/cmd/enumerate_github/README.md index 0c200f2d..9e287d5e 100644 --- a/cmd/enumerate_github/README.md +++ b/cmd/enumerate_github/README.md @@ -13,7 +13,7 @@ $ enumerate_github \ -start 2008-01-01 \ -min-stars=10 \ -workers=1 \ - github_projects.txt + -out=github_projects.txt ``` ## Install @@ -25,10 +25,11 @@ $ go install github.com/ossf/criticality_score/cmd/enumerate_github ## Usage ```shell -$ enumerate_github [FLAGS]... FILE +$ enumerate_github [FLAGS]... ``` -The URL for each repository is written to `FILE`. If `FILE` is `-` the results will be written to STDOUT. +The URL for each repository is written to the output. By default `stdout` is used +for output. `FLAGS` are optional. See below for documentation. @@ -50,8 +51,13 @@ $ export GITHUB_TOKEN=ghp_abc,ghp_123 #### Output flags +- `-out FILE` specify the `FILE` to use for output. By default `stdout` is used. - `-append` appends output to `FILE` if it already exists. - `-force` overwrites `FILE` if it already exists and `-append` is not set. +- `-format {text|scorecard}` indicates the format to use for output. `text` is + used by default and consists of one URL per line. `scorecard` outputs a CSV + file compatible with the [scorecard](https://github.com/ossf/scorecard) + project. If `FILE` exists and neither `-append` nor `-force` is set the command will fail. @@ -119,7 +125,7 @@ Rather than installing the binary, use `go run` to run the command. For example: ```shell -$ go run ./cmd/enumerate_github [FLAGS]... FILE +$ go run ./cmd/enumerate_github [FLAGS]... ``` Limiting the data allows for runs to be completed quickly. For example: @@ -129,6 +135,5 @@ $ go run ./cmd/enumerate_github \ -log=debug \ -start=2022-06-14 \ -end=2022-06-21 \ - -min-stars=20 \ - - + -min-stars=20 ``` \ No newline at end of file diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 9db6d24f..8acf05cc 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -52,6 +52,7 @@ const ( var ( // epochDate is the earliest date for which GitHub has data. epochDate = time.Date(2008, 1, 1, 0, 0, 0, 0, time.UTC) + runID = time.Now().UTC().Format(runIDDateFormat) minStarsFlag = flag.Int("min-stars", 10, "only enumerates repositories with this or more of stars.") starOverlapFlag = flag.Int("star-overlap", 5, "the number of stars to overlap between queries.") @@ -72,6 +73,7 @@ var ( "CRITICALITY_SCORE_WORKERS": "workers", "CRITICALITY_SCORE_START_DATE": "start", "CRITICALITY_SCORE_END_DATE": "end", + "CRITICALITY_SCORE_OUTFILE": "out", "CRITICALITY_SCORE_OUTFILE_FORCE": "force", "CRITICALITY_SCORE_QUERY": "query", "CRITICALITY_SCORE_STARS_MIN": "min-stars", @@ -107,13 +109,13 @@ func init() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&format, "format", repowriter.WriterTypeText, "set output file `format`.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") - outfile.DefineFlags(flag.CommandLine, "force", "append", "FILE") + outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) w := flag.CommandLine.Output() - fmt.Fprintf(w, "Usage:\n %s [FLAGS]... FILE\n\n", cmdName) + fmt.Fprintf(w, "Usage:\n %s [FLAGS]...\n\n", cmdName) fmt.Fprintf(w, "Enumerates GitHub repositories between -start date and -end date, with -min-stars\n") - fmt.Fprintf(w, "or higher. Writes each repository URL on a separate line to FILE.\n") + fmt.Fprintf(w, "or higher. Writes each repository URL in the specified format.\n") fmt.Fprintf(w, "\nFlags:\n") flag.PrintDefaults() } @@ -158,6 +160,17 @@ func main() { } defer logger.Sync() + // Set a FilenameTransform to expand the run-id token in a filename. + outfile.DefaultOpener.FilenameTransform = func(f string) string { + if !strings.Contains(f, runIDToken) { + return f + } + // Every future log message will have the run-id attached. + logger = logger.With(zap.String("run-id", runID)) + logger.Info("Using Run ID") + return strings.ReplaceAll(f, runIDToken, runID) + } + // roundtripper requires us to use the scorecard logger. innerLogger := zapr.NewLogger(logger) scLogger := &sclog.Logger{Logger: &innerLogger} @@ -179,29 +192,8 @@ func main() { os.Exit(2) } - // Ensure a non-flag argument (the output file) is specified. - if flag.NArg() != 1 { - logger.Error("An output file must be specified.") - os.Exit(2) - } - outFilename := flag.Arg(0) - - // Expand runIDToken into the runID inside the output file's name. - if strings.Contains(outFilename, runIDToken) { - runID := time.Now().UTC().Format(runIDDateFormat) - // Every future log message will have the run-id attached. - logger = logger.With(zap.String("run-id", runID)) - logger.Info("Using Run ID") - outFilename = strings.ReplaceAll(outFilename, runIDToken, runID) - } - - // Print a helpful message indicating the configuration we're using. - logger.With( - zap.String("filename", outFilename), - ).Info("Preparing output file") - // Open the output file - out, err := outfile.Open(context.Background(), outFilename) + out, err := outfile.Open(context.Background()) if err != nil { // File failed to open logger.Error("Failed to open output file", zap.Error(err)) @@ -273,6 +265,6 @@ func main() { logger.With( zap.Int("total_repos", totalRepos), zap.Duration("duration", time.Since(startTime).Truncate(time.Minute)), - zap.String("filename", outFilename), + zap.String("filename", out.Name()), ).Info("Finished enumeration") } diff --git a/cmd/scorer/README.md b/cmd/scorer/README.md index 782d91fb..fbb61536 100644 --- a/cmd/scorer/README.md +++ b/cmd/scorer/README.md @@ -10,8 +10,8 @@ The input of this tool is usually the output of the `collect_signals` tool. ```shell $ scorer \ -config config/scorer/original_pike.yml \ - raw_signals.txt \ - scored_signals.txt + -out=scored_signals.txt \ + raw_signals.txt ``` ## Install @@ -23,14 +23,14 @@ $ go install github.com/ossf/criticality_score/cmd/scorer ## Usage ```shell -$ scorer [FLAGS]... IN_FILE OUT_FILE +$ scorer [FLAGS]... IN_FILE ``` Raw signals are read as CSV from `IN_FILE`. If `-` is passed in for `IN_FILE` raw signal data will read from STDIN rather than a file. -Results are re-written in CSV format to `OUT_FILE`. If `OUT_FILE` is `-` the -results will be written to STDOUT. Results are sorted in descending score order. +Results are re-written in CSV format to the output in descending score order. +By default `stdout` is used for output. The `-config` flag is required. All other `FLAGS` are optional. See below for documentation. @@ -39,6 +39,7 @@ See below for documentation. #### Output flags +- `-out FILE` specify the `FILE` to use for output. By default `stdout` is used. - `-append` appends output to `OUT_FILE` if it already exists. - `-force` overwrites `OUT_FILE` if it already exists and `-append` is not set. @@ -131,7 +132,7 @@ Rather than installing the binary, use `go run` to run the command. For example: ```shell -$ go run ./cmd/scorer [FLAGS]... IN_FILE OUT_FILE +$ go run ./cmd/scorer [FLAGS]... IN_FILE ``` Use STDIN and STDOUT on a subset of data for fast iteration. For example: @@ -139,5 +140,5 @@ Use STDIN and STDOUT on a subset of data for fast iteration. For example: ```shell $ head -10 raw_signals.csv | go run ./cmd/scorer \ -config config/scorer/original_pike.yml \ - - - + - ``` \ No newline at end of file diff --git a/cmd/scorer/main.go b/cmd/scorer/main.go index 97a880d6..fe926f80 100644 --- a/cmd/scorer/main.go +++ b/cmd/scorer/main.go @@ -63,7 +63,7 @@ var ( func init() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") - outfile.DefineFlags(flag.CommandLine, "force", "append", "OUT_FILE") // TODO: add the ability to disable "append" + outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "OUT_FILE") // TODO: add the ability to disable "append" flag.Usage = func() { cmdName := path.Base(os.Args[0]) w := flag.CommandLine.Output() @@ -111,12 +111,11 @@ func main() { } defer logger.Sync() - if flag.NArg() != 2 { - logger.Error("Must have an input file and an output file specified") + if flag.NArg() != 1 { + logger.Error("Must have an input file specified.") os.Exit(2) } inFilename := flag.Args()[0] - outFilename := flag.Args()[1] // Open the in-file for reading var r *csv.Reader @@ -132,11 +131,10 @@ func main() { r = csv.NewReader(fr) // Open the out-file for writing - fw, err := outfile.Open(context.Background(), outFilename) + fw, err := outfile.Open(context.Background()) if err != nil { logger.With( zap.Error(err), - zap.String("filename", outFilename), ).Error("Failed to open file for output") os.Exit(2) } diff --git a/go.work.sum b/go.work.sum index 9dafb0b3..88a602de 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,8 +1,7 @@ -github.com/Abirdcfly/dupword v0.0.7 h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/kkHAIKE/contextcheck v1.1.2 h1:BYUSG/GhMhqVz//yjl8IkBDlMEws+9DtCmkz18QO1gg= +github.com/google/go-github/v38 v38.1.0 h1:C6h1FkaITcBFK7gAmq4eFzt6gbhEhk7L5z6R3Uva+po= +github.com/jszwec/csvutil v1.6.0 h1:QORXquCT0t8nUKD7utAD4HDmQMgG0Ir9WieZXzpa7ms= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= @@ -11,9 +10,7 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc= google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml index 9784b255..157add66 100644 --- a/infra/k8s/enumerate_github.yaml +++ b/infra/k8s/enumerate_github.yaml @@ -27,13 +27,14 @@ spec: containers: - name: enumerate-github image: gcr.io/openssf/criticality-score-enumerate-github:latest - args: ["gs://ossf-criticality-score-url-data/[[runid]]/github.csv"] imagePullPolicy: Always env: - name: GITHUB_AUTH_SERVER value: "10.4.4.210:80" - name: CRITICALITY_SCORE_LOG_ENV value: "gcp" + - name: CRITICALITY_SCORE_OUTFILE + value: "gs://ossf-criticality-score-url-data/[[runid]]/github.csv" - name: CRITICALITY_SCORE_OUTFILE_FORCE value: "1" - name: CRITICALITY_SCORE_STARS_MIN diff --git a/infra/test/docker-compose.yml b/infra/test/docker-compose.yml index 5d2a9601..7d0df96e 100644 --- a/infra/test/docker-compose.yml +++ b/infra/test/docker-compose.yml @@ -42,8 +42,8 @@ services: enumerate-github: image: criticality-score-enumerate-github:latest - command: s3://criticality_score/enumeration/[[runid]]/github.txt?endpoint=minio:9000&disableSSL=true&s3ForcePathStyle=true environment: + CRITICALITY_SCORE_OUTFILE: s3://criticality_score/enumeration/[[runid]]/github.txt?endpoint=minio:9000&disableSSL=true&s3ForcePathStyle=true CRITICALITY_SCORE_OUTFILE_FORCE: 1 CRITICALITY_SCORE_STARS_MIN: ${CRITICALITY_SCORE_STARS_MIN:-100} CRITICALITY_SCORE_START_DATE: ${CRITICALITY_SCORE_START_DATE} diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index 2ee365dd..32946215 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -33,33 +33,60 @@ import ( // fileOpenFunc makes it possible to mock os.OpenFile() for testing. type fileOpenFunc func(string, int, os.FileMode) (*os.File, error) +// A FilenameTransform applies a transform to the filename before it used to +// open a file. +type FilenameTransform func(string) string + +// NameWriteCloser implements the io.WriteCloser interface, but also allows a +// a name to be returned so that the object can be identified. +type NameWriteCloser interface { + // Name returns a name for the Writer. + Name() string + io.WriteCloser +} + +type writeCloserWrapper struct { + io.WriteCloser + name string +} + +// Name implements the NameWriteCloser interface. +func (w *writeCloserWrapper) Name() string { + if w == nil { + return "" + } + return w.name +} + type Opener struct { - fileOpener fileOpenFunc - StdoutName string - forceFlag string - force bool - append bool - Perm os.FileMode + FilenameTransform FilenameTransform + fileOpener fileOpenFunc + filename string + forceFlag string + force bool + append bool + Perm os.FileMode } -// CreateOpener creates an Opener and defines the sepecified flags forceFlag and appendFlag. -func CreateOpener(fs *flag.FlagSet, forceFlag, appendFlag, fileHelpName string) *Opener { +// CreateOpener creates an Opener and defines the sepecified flags fileFlag, forceFlag and appendFlag. +func CreateOpener(fs *flag.FlagSet, fileFlag, forceFlag, appendFlag, fileHelpName string) *Opener { o := &Opener{ - Perm: 0o666, - StdoutName: "-", - fileOpener: os.OpenFile, - forceFlag: forceFlag, + Perm: 0o666, + FilenameTransform: func(f string) string { return f }, + fileOpener: os.OpenFile, + forceFlag: forceFlag, } + fs.StringVar(&(o.filename), fileFlag, "", fmt.Sprintf("use the file `%s` for output. Defaults to stdout if not set.", fileHelpName)) fs.BoolVar(&(o.force), forceFlag, false, fmt.Sprintf("overwrites %s if it already exists and -%s is not set.", fileHelpName, appendFlag)) fs.BoolVar(&(o.append), appendFlag, false, fmt.Sprintf("appends to %s if it already exists.", fileHelpName)) return o } -func (o *Opener) openFile(filename string, extraFlags int) (io.WriteCloser, error) { +func (o *Opener) openFile(filename string, extraFlags int) (NameWriteCloser, error) { return o.fileOpener(filename, os.O_WRONLY|os.O_SYNC|os.O_CREATE|extraFlags, o.Perm) } -func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, error) { +func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (NameWriteCloser, error) { if o.append || !o.force { return nil, fmt.Errorf("blob store must use -%s flag", o.forceFlag) } @@ -78,12 +105,16 @@ func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, if err != nil { return nil, fmt.Errorf("failed creating writer for %s/%s: %w", bucket, prefix, err) } - return w, nil + return &writeCloserWrapper{ + WriteCloser: w, + name: u.String(), + }, nil } -// Open opens and returns a file for output with the given filename. +// Open opens and returns a file for output with the filename set by the fileFlag, +// applying any transform set in FilenameTransform. // -// If filename is equal to o.StdoutName, os.Stdout will be used. +// If filename is empty/unset, os.Stdout will be used. // If filename does not exist, it will be created with the mode set in o.Perm. // If filename does exist, the behavior of this function will depend on the // flags: @@ -94,33 +125,34 @@ func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (io.WriteCloser, // truncated. // - if neither forceFlag nor appendFlag are set an error will be // returned. -func (o *Opener) Open(ctx context.Context, filename string) (io.WriteCloser, error) { - if o.StdoutName != "" && filename == o.StdoutName { +func (o *Opener) Open(ctx context.Context) (NameWriteCloser, error) { + f := o.FilenameTransform(o.filename) + if f == "" { return os.Stdout, nil - } else if u, e := url.Parse(filename); e == nil && u.IsAbs() { + } else if u, e := url.Parse(f); e == nil && u.IsAbs() { return o.openBlobStore(ctx, u) } switch { case o.append: - return o.openFile(filename, os.O_APPEND) + return o.openFile(f, os.O_APPEND) case o.force: - return o.openFile(filename, os.O_TRUNC) + return o.openFile(f, os.O_TRUNC) default: - return o.openFile(filename, os.O_EXCL) + return o.openFile(f, os.O_EXCL) } } -var defaultOpener *Opener +var DefaultOpener *Opener // DefineFlags is a wrapper around CreateOpener for updating a default instance // of Opener. -func DefineFlags(fs *flag.FlagSet, forceFlag, appendFlag, fileHelpName string) { - defaultOpener = CreateOpener(fs, forceFlag, appendFlag, fileHelpName) +func DefineFlags(fs *flag.FlagSet, fileFlag, forceFlag, appendFlag, fileHelpName string) { + DefaultOpener = CreateOpener(fs, fileFlag, forceFlag, appendFlag, fileHelpName) } // Open is a wrapper around Opener.Open for the default instance of Opener. // // Must only be called after DefineFlags. -func Open(ctx context.Context, filename string) (io.WriteCloser, error) { - return defaultOpener.Open(ctx, filename) +func Open(ctx context.Context) (NameWriteCloser, error) { + return DefaultOpener.Open(ctx) } diff --git a/internal/outfile/outfile_test.go b/internal/outfile/outfile_test.go index e37609f3..7fd84ab2 100644 --- a/internal/outfile/outfile_test.go +++ b/internal/outfile/outfile_test.go @@ -18,6 +18,7 @@ import ( "context" "errors" "flag" + "fmt" "os" "testing" ) @@ -35,12 +36,12 @@ type testOpener struct { opener *Opener } -func newTestOpener() *testOpener { +func newTestOpener(t *testing.T) *testOpener { + t.Helper() o := &testOpener{} o.flag = flag.NewFlagSet("", flag.ContinueOnError) - o.opener = CreateOpener(o.flag, "force", "append", "FILE") + o.opener = CreateOpener(o.flag, "out", "force", "append", "FILE") o.opener.Perm = 0o567 - o.opener.StdoutName = "-stdout-" o.opener.fileOpener = func(filename string, flags int, perm os.FileMode) (*os.File, error) { o.lastOpen = &openCall{ filename: filename, @@ -50,14 +51,18 @@ func newTestOpener() *testOpener { if o.openErr != nil { return nil, o.openErr } else { - return &os.File{}, nil + dir := t.TempDir() + if err := os.Chdir(dir); err != nil { + return nil, err + } + return os.Create(filename) } } return o } func TestForceFlagDefined(t *testing.T) { - o := newTestOpener() + o := newTestOpener(t) f := o.flag.Lookup("force") if f == nil { t.Fatal("Lookup() == nil, wanted a flag.") @@ -65,7 +70,7 @@ func TestForceFlagDefined(t *testing.T) { } func TestAppendFlagDefined(t *testing.T) { - o := newTestOpener() + o := newTestOpener(t) f := o.flag.Lookup("append") if f == nil { t.Fatal("Lookup() == nil, wanted a flag.") @@ -73,8 +78,8 @@ func TestAppendFlagDefined(t *testing.T) { } func TestOpenStdout(t *testing.T) { - o := newTestOpener() - f, err := o.opener.Open(context.Background(), "-stdout-") + o := newTestOpener(t) + f, err := o.opener.Open(context.Background()) if err != nil { t.Fatalf("Open() == %v, want nil", err) } @@ -84,9 +89,9 @@ func TestOpenStdout(t *testing.T) { } func TestOpenBucketUrl(t *testing.T) { - o := newTestOpener() - o.flag.Parse([]string{"-force"}) - f, err := o.opener.Open(context.Background(), "mem://bucket/prefix") + o := newTestOpener(t) + o.flag.Parse([]string{"-force", "-out=mem://bucket/prefix"}) + f, err := o.opener.Open(context.Background()) if err != nil { t.Fatalf("Open() == %v, want nil", err) } @@ -99,9 +104,9 @@ func TestOpenBucketUrl(t *testing.T) { } func TestOpenBucketUrlNoForceFlag(t *testing.T) { - o := newTestOpener() - o.flag.Parse([]string{}) - _, err := o.opener.Open(context.Background(), "mem://bucket/prefix") + o := newTestOpener(t) + o.flag.Parse([]string{"-out=mem://bucket/prefix"}) + _, err := o.opener.Open(context.Background()) if err == nil { t.Fatalf("Open() == nil, want an error") } @@ -140,26 +145,29 @@ func TestOpenFlagTest(t *testing.T) { // Test success responses for _, test := range tests { t.Run(test.name, func(t *testing.T) { - o := newTestOpener() - o.flag.Parse(test.args) - f, err := o.opener.Open(context.Background(), "path/to/file") + o := newTestOpener(t) + o.flag.Parse(append(test.args, "-out=testfile")) + f, err := o.opener.Open(context.Background()) if err != nil { t.Fatalf("Open() == %v, want nil", err) } if f == nil { t.Fatal("Open() == nil, want a file") } - assertLastOpen(t, o, "path/to/file", test.expectedFlag, 0o567) + if got := f.Name(); got != "testfile" { + t.Fatalf("Open().Name() == %s; want %s", got, "testfile") + } + assertLastOpen(t, o, "testfile", test.expectedFlag, 0o567) }) } // Test error responses for _, test := range tests { t.Run(test.name+" error", func(t *testing.T) { - o := newTestOpener() - o.flag.Parse(test.args) + o := newTestOpener(t) + o.flag.Parse(append(test.args, "-out=testfile")) o.openErr = errors.New("test error") - _, err := o.opener.Open(context.Background(), "path/to/file") + _, err := o.opener.Open(context.Background()) if err == nil { t.Fatalf("Open() is nil, want %v", o.openErr) } @@ -182,3 +190,21 @@ func assertLastOpen(t *testing.T, o *testOpener, filename string, requireFlags i t.Fatalf("Open(_, _, %v) called, want Open(_, _, %v)", o.lastOpen.perm, perm) } } + +func TestFilenameTransform(t *testing.T) { + want := "prefix-testfile-suffix" + o := newTestOpener(t) + o.opener.FilenameTransform = func(f string) string { return fmt.Sprintf("prefix-%s-suffix", f) } + o.flag.Parse([]string{"-out=testfile"}) + f, err := o.opener.Open(context.Background()) + if err != nil { + t.Fatalf("Open() == %v, want nil", err) + } + if f == nil { + t.Fatal("Open() == nil, want a file") + } + if got := f.Name(); got != want { + t.Fatalf("Open().Name() == %s; want %s", got, want) + } + assertLastOpen(t, o, want, os.O_EXCL, 0o567) +} From 5ffcd56b01f6fd02edb7af943f6b23131ae4e9cf Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 4 Nov 2022 18:51:03 +1100 Subject: [PATCH 118/172] Change how repo URL are input into criticality_score + and create a docker image (#229) This aligns more closely to the original Python implementation, and is easier for someone using the tool from the command line. Additionally create a docker container for the criticality_score binary. Signed-off-by: Caleb Brown --- .dockerignore | 12 +++ Makefile | 4 +- cmd/criticality_score/Dockerfile | 30 +++++++ cmd/criticality_score/README.md | 32 +++---- cmd/criticality_score/input.go | 139 +++++++++++++++++++++++++++++++ cmd/criticality_score/main.go | 46 +++++----- 6 files changed, 225 insertions(+), 38 deletions(-) create mode 100644 .dockerignore create mode 100644 cmd/criticality_score/Dockerfile create mode 100644 cmd/criticality_score/input.go diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..aa85271f --- /dev/null +++ b/.dockerignore @@ -0,0 +1,12 @@ +# Ignore irrelevant files +.github +infra +docs +images + +# Ignore Dockerfile - this improve caching. +**/Dockerfile + +# Ignore the deprecated Python project +criticality_score +*.py \ No newline at end of file diff --git a/Makefile b/Makefile index ee511aaf..b22e947e 100644 --- a/Makefile +++ b/Makefile @@ -33,9 +33,11 @@ lint: ## Run linter lint: $(GOLANGCI_LINT) $(GOLANGCI_LINT) run -c .golangci.yml -docker-targets = build/docker/enumerate-github +docker-targets = build/docker/enumerate-github build/docker/criticality-score .PHONY: build/docker $(docker-targets) build/docker: $(docker-targets) ## Build all docker targets +build/docker/criticality-score: + DOCKER_BUILDKIT=1 docker build . -f cmd/criticality_score/Dockerfile --tag $(IMAGE_NAME)-cli build/docker/enumerate-github: DOCKER_BUILDKIT=1 docker build . -f cmd/enumerate_github/Dockerfile --tag $(IMAGE_NAME)-enumerate-github diff --git a/cmd/criticality_score/Dockerfile b/cmd/criticality_score/Dockerfile new file mode 100644 index 00000000..ac5cf23e --- /dev/null +++ b/cmd/criticality_score/Dockerfile @@ -0,0 +1,30 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +FROM golang@sha256:122f3484f844467ebe0674cf57272e61981770eb0bc7d316d1f0be281a88229f AS base +WORKDIR /src +ENV CGO_ENABLED=0 +COPY go.mod go.sum ./ +RUN go mod download +COPY . ./ + +FROM base AS criticality_score +ARG TARGETOS +ARG TARGETARCH +RUN CGO_ENABLED=0 go build ./cmd/criticality_score + +FROM gcr.io/distroless/base:nonroot@sha256:533c15ef2acb1d3b1cd4e58d8aa2740900cae8f579243a53c53a6e28bcac0684 +COPY --from=criticality_score /src/criticality_score ./criticality_score +COPY --from=criticality_score --chmod=775 /src/config/scorer/* ./config/scorer/ +ENTRYPOINT ["./criticality_score"] diff --git a/cmd/criticality_score/README.md b/cmd/criticality_score/README.md index 7e3270d4..a69a0ffb 100644 --- a/cmd/criticality_score/README.md +++ b/cmd/criticality_score/README.md @@ -25,11 +25,14 @@ $ go install github.com/ossf/criticality_score/cmd/criticality_score ## Usage ```shell -$ criticality_score [FLAGS]... IN_FILE +$ criticality_score [FLAGS]... {FILE|REPO...} ``` -Project repository URLs are read from the specified `IN_FILE`. If `-` is passed -in as an `IN_FILE` URLs will read from STDIN. +Project repository URLs are read either from the specified `FILE`, or from the +command line arguments. +If `-` is passed in as an `FILE` URLs will read from STDIN. If `FILE` does not +exist it will be treated as a `REPO`. +Each `REPO` is a project repository URLs. Results are written in CSV format to the output. By default `stdout` is used for output. @@ -38,7 +41,8 @@ output. ### Authentication -`criticality_score` requires authentication to GitHub, and optionally Google Cloud Platform to run. +`criticality_score` requires authentication to GitHub, and optionally Google +Cloud Platform to run. #### GitHub Authentication @@ -104,11 +108,12 @@ See more on GCP #### Output flags -- `-out FILE` specify the `FILE` to use for output. By default `stdout` is used. -- `-append` appends output to `FILE` if it already exists. -- `-force` overwrites `FILE` if it already exists and `-append` is not set. +- `-out OUTFILE` specify the `OUTFILE` to use for output. By default `stdout` is used. +- `-append` appends output to `OUTFILE` if it already exists. +- `-force` overwrites `OUTFILE` if it already exists and `-append` is not set. -If `FILE` exists and neither `-append` nor `-force` is set the command will fail. +If `OUTFILE` exists and neither `-append` nor `-force` is set the command will +fail. #### Google Cloud Platform flags @@ -194,14 +199,13 @@ Rather than installing the binary, use `go run` to run the command. For example: ```shell -$ go run ./cmd/criticality_score [FLAGS]... IN_FILE... +$ go run ./cmd/criticality_score [FLAGS]... {FILE|REPO...} ``` -Pass in a single repo using echo to quickly test signal collection, for example: +Pass in a single repo to quickly test signal collection, for example: ```shell -$ echo "https://github.com/django/django" | \ - go run ./cmd/criticality_score \ - -log=debug \ - - +$ go run ./cmd/criticality_score \ + -log=debug \ + https://github.com/django/django ``` \ No newline at end of file diff --git a/cmd/criticality_score/input.go b/cmd/criticality_score/input.go new file mode 100644 index 00000000..abd4a21a --- /dev/null +++ b/cmd/criticality_score/input.go @@ -0,0 +1,139 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package main + +import ( + "bufio" + "context" + "errors" + "io" + "net/url" + "os" + + "github.com/ossf/criticality_score/internal/infile" +) + +// iter is a simple interface for iterating across a list of items. +// +// This interface is modeled on the bufio.Scanner behavior. +type iter[T any] interface { + // Item returns the current item in the iterator + Item() T + + // Next advances the iterator to the next item and returns true if there is + // an item to consume, and false if the end of the input has been reached, + // or there has been an error. + // + // Next must be called before each call to Item. + Next() bool + + // Err returns any error produced while iterating. + Err() error +} + +// iterCloser is an iter, but also embeds the io.Closer interface, so it can be +// used to wrap a file for iterating through. +type iterCloser[T any] interface { + iter[T] + io.Closer +} + +// scannerIter implements iter using a bufio.Scanner to iterate through lines in +// a file. +type scannerIter struct { + r io.ReadCloser + scanner *bufio.Scanner +} + +func (i *scannerIter) Item() string { + return i.scanner.Text() +} + +func (i *scannerIter) Next() bool { + return i.scanner.Scan() +} + +func (i *scannerIter) Err() error { + return i.scanner.Err() +} + +func (i *scannerIter) Close() error { + return i.r.Close() +} + +// sliceIter implements iter using a slice for iterating. +type sliceIter[T any] struct { + values []T + next int + size int +} + +func (i *sliceIter[T]) Item() T { + return i.values[i.next-1] +} + +func (i *sliceIter[T]) Next() bool { + if i.next <= i.size { + i.next++ + } + return i.next <= i.size +} + +func (i *sliceIter[T]) Err() error { + return nil +} + +func (i *sliceIter[T]) Close() error { + return nil +} + +// initInput returns an iterCloser for iterating across repositories for +// collecting signals. +// +// If only one arg is specified, the code will treat it as a file and attempt to +// open it. If the file doesn't exist, and is parseable as a URL the arg will be +// treated as a repo. +// +// If more than one arg is specified they are all considered to be repos. +// +// TODO: support the ability to force args to be interpreted as either a file, +// or a list of repos. +func initInput(args []string) (iterCloser[string], error) { + if len(args) == 1 { + // If there is 1 arg, attempt to open it as a file. + fileOrRepo := args[0] + _, err := url.Parse(fileOrRepo) + urlParseFailed := err != nil + + // Open the in-file for reading + r, err := infile.Open(context.Background(), fileOrRepo) + if err == nil { + return &scannerIter{ + r: r, + scanner: bufio.NewScanner(r), + }, nil + } else if err != nil && (urlParseFailed || !errors.Is(err, os.ErrNotExist)) { + // Only report errors if the file doesn't appear to be a URL, or if + // it doesn't exist. + return nil, err + } + } + // If file loading failed, or there are 2 or more args, treat args as a list + // of repos. + return &sliceIter[string]{ + size: len(args), + values: args, + }, nil +} diff --git a/cmd/criticality_score/main.go b/cmd/criticality_score/main.go index 4f971e0d..07b8112b 100644 --- a/cmd/criticality_score/main.go +++ b/cmd/criticality_score/main.go @@ -15,7 +15,6 @@ package main import ( - "bufio" "context" "errors" "flag" @@ -30,7 +29,6 @@ import ( "go.uber.org/zap/zapcore" "github.com/ossf/criticality_score/internal/collector" - "github.com/ossf/criticality_score/internal/infile" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" "github.com/ossf/criticality_score/internal/scorer" @@ -52,22 +50,28 @@ var ( logEnv log.Env ) -func init() { +// initFlags prepares any runtime flags, usage information and parses the flags. +func initFlags() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") - outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "FILE") + outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "OUTFILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) w := flag.CommandLine.Output() - fmt.Fprintf(w, "Usage:\n %s [FLAGS]... IN_FILE OUT_FILE\n\n", cmdName) - fmt.Fprintf(w, "Collects signals for each project repository listed.\n") - fmt.Fprintf(w, "IN_FILE must be either a file or - to read from stdin.\n") - fmt.Fprintf(w, "OUT_FILE must be either be a file or - to write to stdout.\n") + fmt.Fprintf(w, "Usage:\n %s [FLAGS]... {FILE|REPO...}\n\n", cmdName) + fmt.Fprintf(w, "Collects signals for a list of project repository urls.\n\n") + fmt.Fprintf(w, "FILE must be either a file or - to read from stdin. If FILE does not\n") + fmt.Fprintf(w, "exist it will be treated as a REPO.\n") + fmt.Fprintf(w, "Each REPO must be a project repository url.\n") fmt.Fprintf(w, "\nFlags:\n") flag.PrintDefaults() } + flag.Parse() } +// getScorer prepares a Scorer based on the flags passed to the command. +// +// nil will be returned if scoring is disabled. func getScorer(logger *zap.Logger) *scorer.Scorer { if *scoringDisableFlag { logger.Info("Scoring disabled") @@ -112,7 +116,7 @@ func generateScoreColumnName(s *scorer.Scorer) string { } func main() { - flag.Parse() + initFlags() logger, err := log.NewLogger(logEnv, logLevel) if err != nil { @@ -125,8 +129,8 @@ func main() { scoreColumnName := generateScoreColumnName(s) // Complete the validation of args - if flag.NArg() != 1 { - logger.Error("Must have an input file specified.") + if flag.NArg() == 0 { + logger.Error("An input file or at least one repo must be specified.") os.Exit(2) } @@ -152,18 +156,15 @@ func main() { os.Exit(2) } - inFilename := flag.Args()[0] - - // Open the in-file for reading - r, err := infile.Open(context.Background(), inFilename) + // Prepare the input for reading + inputIter, err := initInput(flag.Args()) if err != nil { logger.With( - zap.String("filename", inFilename), zap.Error(err), - ).Error("Failed to open an input file") + ).Error("Failed to prepare input") os.Exit(2) } - defer r.Close() + defer inputIter.Close() // Open the out-file for writing w, err := outfile.Open(context.Background()) @@ -222,10 +223,9 @@ func main() { } }) - // Read in each line from the input files - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := scanner.Text() + // Read in each repo from the input + for inputIter.Next() { + line := inputIter.Item() u, err := url.Parse(strings.TrimSpace(line)) if err != nil { @@ -242,7 +242,7 @@ func main() { // Send the url to the workers repos <- u } - if err := scanner.Err(); err != nil { + if err := inputIter.Err(); err != nil { logger.With( zap.Error(err), ).Error("Failed while reading input") From 56f7cca1e8b89c2d235e17abe8ffa89e1f0bbda7 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 7 Nov 2022 19:55:21 +1100 Subject: [PATCH 119/172] Implement the collect_signals worker for productionization. (#230) * Bump scorecard dep to include worker changes. Signed-off-by: Caleb Brown * Initial implementation of the collect_signals worker for production. It uses the scorecard project's worker implementation to work within the same architecture as scorecard. Signed-off-by: Caleb Brown * Add some more consistent comments. Signed-off-by: Caleb Brown * Improve readability and remove redundant logging. Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- Makefile | 4 +- cmd/collect_signals/Dockerfile | 30 ++++ cmd/collect_signals/main.go | 237 ++++++++---------------------- cmd/collect_signals/worker.go | 156 ++++++++++++++++++++ go.mod | 49 +++--- go.sum | 148 ++++++++----------- go.work.sum | 33 ++++- internal/collector/collector.go | 2 +- internal/collector/config.go | 26 ++-- internal/collector/config_test.go | 2 +- 10 files changed, 382 insertions(+), 305 deletions(-) create mode 100644 cmd/collect_signals/Dockerfile create mode 100644 cmd/collect_signals/worker.go diff --git a/Makefile b/Makefile index b22e947e..3439830c 100644 --- a/Makefile +++ b/Makefile @@ -33,9 +33,11 @@ lint: ## Run linter lint: $(GOLANGCI_LINT) $(GOLANGCI_LINT) run -c .golangci.yml -docker-targets = build/docker/enumerate-github build/docker/criticality-score +docker-targets = build/docker/enumerate-github build/docker/criticality-score build/docker/collect-signals .PHONY: build/docker $(docker-targets) build/docker: $(docker-targets) ## Build all docker targets +build/docker/collect-signals: + DOCKER_BUILDKIT=1 docker build . -f cmd/collect_signals/Dockerfile --tag $(IMAGE_NAME)-collect-signals build/docker/criticality-score: DOCKER_BUILDKIT=1 docker build . -f cmd/criticality_score/Dockerfile --tag $(IMAGE_NAME)-cli build/docker/enumerate-github: diff --git a/cmd/collect_signals/Dockerfile b/cmd/collect_signals/Dockerfile new file mode 100644 index 00000000..b2326af5 --- /dev/null +++ b/cmd/collect_signals/Dockerfile @@ -0,0 +1,30 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +FROM golang@sha256:122f3484f844467ebe0674cf57272e61981770eb0bc7d316d1f0be281a88229f AS base +WORKDIR /src +ENV CGO_ENABLED=0 +COPY go.mod go.sum ./ +RUN go mod download +COPY . ./ + +FROM base AS collect_signals +ARG TARGETOS +ARG TARGETARCH +RUN CGO_ENABLED=0 go build ./cmd/collect_signals + +FROM gcr.io/distroless/base:nonroot@sha256:533c15ef2acb1d3b1cd4e58d8aa2740900cae8f579243a53c53a6e28bcac0684 +COPY --from=collect_signals /src/collect_signals ./collect_signals +COPY --from=collect_signals --chmod=775 /src/config/scorer/* ./config/scorer/ +ENTRYPOINT ["./collect_signals"] diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index afe8bc8d..b16e42d2 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -15,226 +15,111 @@ package main import ( - "bufio" "context" - "errors" "flag" - "fmt" "net/http" - "net/url" - "os" - "path" "strings" + "github.com/ossf/scorecard/v4/cron/config" + "github.com/ossf/scorecard/v4/cron/worker" "go.uber.org/zap" "go.uber.org/zap/zapcore" "github.com/ossf/criticality_score/internal/collector" - "github.com/ossf/criticality_score/internal/infile" log "github.com/ossf/criticality_score/internal/log" - "github.com/ossf/criticality_score/internal/outfile" - "github.com/ossf/criticality_score/internal/scorer" - "github.com/ossf/criticality_score/internal/signalio" ) const defaultLogLevel = zapcore.InfoLevel -var ( - gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") - depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") - depsdevDatasetFlag = flag.String("depsdev-dataset", collector.DefaultGCPDatasetName, "the BigQuery dataset name to use.") - scoringDisableFlag = flag.Bool("scoring-disable", false, "disables the generation of scores.") - scoringConfigFlag = flag.String("scoring-config", "", "path to a YAML file for configuring the scoring algorithm.") - scoringColumnNameFlag = flag.String("scoring-column", "", "manually specify the name for the column used to hold the score.") - logLevel = defaultLogLevel - logEnv log.Env -) +func main() { + flag.Parse() -func init() { - flag.Var(&logLevel, "log", "set the `level` of logging.") - flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") - outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "OUT_FILE") - flag.Usage = func() { - cmdName := path.Base(os.Args[0]) - w := flag.CommandLine.Output() - fmt.Fprintf(w, "Usage:\n %s [FLAGS]... IN_FILE OUT_FILE\n\n", cmdName) - fmt.Fprintf(w, "Collects signals for each project repository listed.\n") - fmt.Fprintf(w, "IN_FILE must be either a file or - to read from stdin.\n") - fmt.Fprintf(w, "OUT_FILE must be either be a file or - to write to stdout.\n") - fmt.Fprintf(w, "\nFlags:\n") - flag.PrintDefaults() + if err := config.ReadConfig(); err != nil { + panic(err) } -} -func getScorer(logger *zap.Logger) *scorer.Scorer { - if *scoringDisableFlag { - logger.Info("Scoring disabled") - return nil - } - if *scoringConfigFlag == "" { - logger.Info("Preparing default scorer") - return scorer.FromDefaultConfig() - } - // Prepare the scorer from the config file - logger = logger.With( - zap.String("filename", *scoringConfigFlag), - ) - logger.Info("Preparing scorer from config") - cf, err := os.Open(*scoringConfigFlag) + // Extract the criticality score specific variables in the config. + criticalityConfig, err := config.GetCriticalityValues() if err != nil { - logger.With( - zap.Error(err), - ).Error("Failed to open scoring config file") - os.Exit(2) + panic(err) } - defer cf.Close() - s, err := scorer.FromConfig(scorer.NameFromFilepath(*scoringConfigFlag), cf) - if err != nil { - logger.With( - zap.Error(err), - ).Error("Failed to initialize scorer") - os.Exit(2) + // Extract the log environment from the config, if it exists. + logEnv := log.DefaultEnv + if val := criticalityConfig["log-env"]; val != "" { + if err := logEnv.UnmarshalText([]byte(val)); err != nil { + panic(err) + } } - return s -} -func generateScoreColumnName(s *scorer.Scorer) string { - if s == nil { - return "" - } - if *scoringColumnNameFlag != "" { - return *scoringColumnNameFlag + // Extract the log level from the config, if it exists. + logLevel := defaultLogLevel + if val := criticalityConfig["log-level"]; val != "" { + if err := logLevel.Set(val); err != nil { + panic(err) + } } - return s.Name() -} - -func main() { - flag.Parse() + // Setup the logger. logger, err := log.NewLogger(logEnv, logLevel) if err != nil { panic(err) } defer logger.Sync() - // Prepare the scorer, if it is enabled. - s := getScorer(logger) - scoreColumnName := generateScoreColumnName(s) + // Extract the GCP project ID. + gcpProjectID, err := config.GetProjectID() + if err != nil { + logger.With(zap.Error(err)).Fatal("Failed to get GCP Project ID") + } - // Complete the validation of args - if flag.NArg() != 1 { - logger.Error("Must have an input file specified.") - os.Exit(2) + // Extract the GCP dataset name. + gcpDatasetName := criticalityConfig["dataset"] + if gcpDatasetName == "" { + gcpDatasetName = collector.DefaultGCPDatasetName } - ctx := context.Background() + // Determine whether scoring is enabled or disabled. + // It supports various "truthy" and "fasley" values. It will default to + // enabled. + scoringState := strings.ToLower(criticalityConfig["scoring"]) + scoringEnabled := true // this value is overridden below + switch scoringState { + case "", "yes", "enabled", "enable", "on", "true", "1": + scoringEnabled = true + case "no", "disabled", "disable", "off", "false", "0": + scoringEnabled = false + default: + // Fatal exits. + logger.Fatal("Unknown 'scoring' setting: " + scoringState) + } + + scoringConfigFile := criticalityConfig["scoring-config"] + scoringColumnName := criticalityConfig["scoring-column-name"] + + // TODO: capture metrics similar to scorecard/cron/worker // Bump the # idle conns per host http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 5 + // Preapre the options for the collector. opts := []collector.Option{ collector.EnableAllSources(), - collector.GCPProject(*gcpProjectFlag), - collector.GCPDatasetName(*depsdevDatasetFlag), - } - if *depsdevDisableFlag { - opts = append(opts, collector.DisableSource(collector.SourceTypeDepsDev)) - } - - c, err := collector.New(ctx, logger, opts...) - if err != nil { - logger.With( - zap.Error(err), - ).Error("Failed to create collector") - os.Exit(2) - } - - inFilename := flag.Args()[0] - - // Open the in-file for reading - r, err := infile.Open(context.Background(), inFilename) - if err != nil { - logger.With( - zap.String("filename", inFilename), - zap.Error(err), - ).Error("Failed to open an input file") - os.Exit(2) + collector.GCPProject(gcpProjectID), + collector.GCPDatasetName(gcpDatasetName), } - defer r.Close() - // Open the out-file for writing - w, err := outfile.Open(context.Background()) + w, err := NewWorker(context.Background(), logger, scoringEnabled, scoringConfigFile, scoringColumnName, opts) if err != nil { - logger.With( - zap.Error(err), - ).Error("Failed to open file for output") - os.Exit(2) + // Fatal exits. + logger.With(zap.Error(err)).Fatal("Failed to create worker") } - defer w.Close() - // Prepare the output writer - extras := []string{} - if s != nil { - extras = append(extras, scoreColumnName) - } - out := signalio.CsvWriter(w, c.EmptySets(), extras...) - - // Read in each line from the input files and process the urls - scanner := bufio.NewScanner(r) - for scanner.Scan() { - line := scanner.Text() - - u, err := url.Parse(strings.TrimSpace(line)) - if err != nil { - logger.With( - zap.String("url", line), - zap.Error(err), - ).Error("Failed to parse project url") - os.Exit(1) // TODO: add a flag to continue or abort on failure - } - - l := logger.With(zap.String("url", u.String())) - l.Debug("Parsed project url") - - ss, err := c.Collect(ctx, u) - if err != nil { - if errors.Is(err, collector.ErrUncollectableRepo) { - l.With( - zap.Error(err), - ).Warn("Repo cannot be collected") - return - } - l.With( - zap.Error(err), - ).Error("Failed to collect signals for repo") - os.Exit(1) // TODO: pass up the error - } - - // If scoring is enabled, prepare the extra data to be output. - extras := []signalio.Field{} - if s != nil { - f := signalio.Field{ - Key: scoreColumnName, - Value: fmt.Sprintf("%.5f", s.Score(ss)), - } - extras = append(extras, f) - } - - // Write the signals to storage. - if err := out.WriteSignals(ss, extras...); err != nil { - l.With( - zap.Error(err), - ).Error("Failed to write signal set") - os.Exit(1) // TODO: pass up the error - } - } - if err := scanner.Err(); err != nil { - logger.With( - zap.Error(err), - ).Error("Failed while reading input") - os.Exit(2) + loop := worker.NewWorkLoop(w) + if err := loop.Run(); err != nil { + // Fatal exits. + logger.With(zap.Error(err)).Fatal("Worker run loop failed") } - // TODO: track metrics as we are running to measure coverage of data + logger.Info("Done.") } diff --git a/cmd/collect_signals/worker.go b/cmd/collect_signals/worker.go new file mode 100644 index 00000000..5041375e --- /dev/null +++ b/cmd/collect_signals/worker.go @@ -0,0 +1,156 @@ +package main + +import ( + "bytes" + "context" + "errors" + "fmt" + "net/url" + "os" + + "github.com/ossf/scorecard/v4/cron/data" + "github.com/ossf/scorecard/v4/cron/worker" + "go.uber.org/zap" + + "github.com/ossf/criticality_score/internal/collector" + "github.com/ossf/criticality_score/internal/scorer" + "github.com/ossf/criticality_score/internal/signalio" +) + +type collectWorker struct { + logger *zap.Logger + c *collector.Collector + s *scorer.Scorer + scoreColumnName string +} + +// Process implements the worker.Worker interface. +func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchRequest, bucketURL string) error { + filename := worker.ResultFilename(req) + + // Prepare the logger with identifiers for the shard and job. + logger := w.logger.With( + zap.Int32("shard_id", req.GetShardNum()), + zap.Time("job_time", req.GetJobTime().AsTime()), + zap.String("filename", filename), + ) + logger.Info("Processing shard") + + // Prepare the output writer + extras := []string{} + if w.s != nil { + extras = append(extras, w.scoreColumnName) + } + var output bytes.Buffer + out := signalio.CsvWriter(&output, w.c.EmptySets(), extras...) + + // Iterate through the repos in this shard. + for _, repo := range req.GetRepos() { + rawURL := repo.GetUrl() + if rawURL == "" { + logger.Warn("Skipping empty repo URL") + continue + } + + // Create a logger for this repo. + repoLogger := logger.With(zap.String("repo", rawURL)) + repoLogger.Info("Processing repo") + + // Parse the URL to ensure it is a URL. + u, err := url.Parse(rawURL) + if err != nil { + // TODO: record a metric + repoLogger.With(zap.Error(err)).Warn("Failed to parse repo URL") + continue + } + ss, err := w.c.Collect(ctx, u) + if err != nil { + if errors.Is(err, collector.ErrUncollectableRepo) { + repoLogger.With(zap.Error(err)).Warn("Repo is uncollectable") + continue + } + return fmt.Errorf("failed during signal collection: %w", err) + } + + // If scoring is enabled, prepare the extra data to be output. + extras := []signalio.Field{} + if w.s != nil { + f := signalio.Field{ + Key: w.scoreColumnName, + Value: fmt.Sprintf("%.5f", w.s.Score(ss)), + } + extras = append(extras, f) + } + + // Write the signals to storage. + if err := out.WriteSignals(ss, extras...); err != nil { + return fmt.Errorf("failed writing signals: %w", err) + } + } + + // Write to the canonical bucket last. The presence of the file indicates + // the job was completed. See scorecard's worker package for details. + if err := data.WriteToBlobStore(ctx, bucketURL, filename, output.Bytes()); err != nil { + return fmt.Errorf("error writing to blob store: %w", err) + } + + logger.Info("Shard written successfully") + + return nil +} + +func getScorer(logger *zap.Logger, scoringEnabled bool, scoringConfigFile string) (*scorer.Scorer, error) { + logger.Debug("Creating scorer") + + if !scoringEnabled { + logger.Info("Scoring: disabled") + return nil, nil + } + if scoringConfigFile == "" { + logger.Info("Scoring: using default config") + return scorer.FromDefaultConfig(), nil + } + logger.With(zap.String("filename", scoringConfigFile)).Info("Scoring: using config file") + + f, err := os.Open(scoringConfigFile) + if err != nil { + return nil, fmt.Errorf("opening config: %w", err) + } + defer f.Close() + + s, err := scorer.FromConfig(scorer.NameFromFilepath(scoringConfigFile), f) + if err != nil { + return nil, fmt.Errorf("from config: %w", err) + } + return s, nil +} + +func NewWorker(ctx context.Context, logger *zap.Logger, scoringEnabled bool, scoringConfigFile, scoringColumn string, collectOpts []collector.Option) (*collectWorker, error) { + logger.Info("Initializing worker") + + c, err := collector.New(ctx, logger, collectOpts...) + if err != nil { + return nil, fmt.Errorf("collector: %w", err) + } + + s, err := getScorer(logger, scoringEnabled, scoringConfigFile) + if err != nil { + return nil, fmt.Errorf("scorer: %w", err) + } + + // If we have the scorer, and the column isn't overridden, use the scorer's + // name. + if s != nil && scoringColumn == "" { + scoringColumn = s.Name() + } + + return &collectWorker{ + logger: logger, + c: c, + s: s, + scoreColumnName: scoringColumn, + }, nil +} + +// PostProcess implements the worker.Worker interface. +func (w *collectWorker) PostProcess() {} diff --git a/go.mod b/go.mod index 9591da9c..902b0144 100644 --- a/go.mod +++ b/go.mod @@ -3,25 +3,26 @@ module github.com/ossf/criticality_score go 1.19 require ( - cloud.google.com/go/bigquery v1.32.0 + cloud.google.com/go/bigquery v1.43.0 github.com/blendle/zapdriver v1.3.1 github.com/go-logr/zapr v1.2.3 github.com/google/go-cmp v0.5.9 github.com/google/go-github/v47 v47.1.0 github.com/iancoleman/strcase v0.2.0 - github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 + github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 go.uber.org/zap v1.23.0 gocloud.dev v0.26.0 - google.golang.org/api v0.88.0 + google.golang.org/api v0.99.0 gopkg.in/yaml.v3 v3.0.1 ) require ( - cloud.google.com/go v0.102.1 // indirect - cloud.google.com/go/compute v1.7.0 // indirect - cloud.google.com/go/iam v0.3.0 // indirect - cloud.google.com/go/storage v1.25.0 // indirect + cloud.google.com/go v0.104.0 // indirect + cloud.google.com/go/compute v1.10.0 // indirect + cloud.google.com/go/iam v0.5.0 // indirect + cloud.google.com/go/pubsub v1.26.0 // indirect + cloud.google.com/go/storage v1.27.0 // indirect github.com/aws/aws-sdk-go v1.43.31 // indirect github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect @@ -42,31 +43,37 @@ require ( github.com/aws/smithy-go v1.11.2 // indirect github.com/benbjohnson/clock v1.1.0 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect - github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect + github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/golang-jwt/jwt/v4 v4.4.1 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect - github.com/google/go-github/v41 v41.0.0 // indirect + github.com/google/go-github/v38 v38.1.0 // indirect + github.com/google/go-github/v45 v45.2.0 // indirect github.com/google/go-querystring v1.1.0 // indirect github.com/google/uuid v1.3.0 // indirect github.com/google/wire v0.5.0 // indirect - github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect - github.com/googleapis/gax-go/v2 v2.4.0 // indirect + github.com/googleapis/enterprise-certificate-proxy v0.2.0 // indirect + github.com/googleapis/gax-go/v2 v2.6.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/jszwec/csvutil v1.7.1 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect - github.com/sirupsen/logrus v1.8.1 // indirect + github.com/sirupsen/logrus v1.9.0 // indirect go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect - golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e // indirect - golang.org/x/net v0.0.0-20220722155237-a158d28d115b // indirect - golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect - golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f // indirect + golang.org/x/crypto v0.1.0 // indirect + golang.org/x/net v0.1.0 // indirect + golang.org/x/oauth2 v0.1.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.1.0 // indirect + golang.org/x/text v0.4.0 // indirect + golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20220720214146-176da50484ac // indirect - google.golang.org/grpc v1.48.0 // indirect - google.golang.org/protobuf v1.28.0 // indirect + google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b // indirect + google.golang.org/grpc v1.50.1 // indirect + google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 6a9949e3..d004dd10 100644 --- a/go.sum +++ b/go.sum @@ -29,34 +29,31 @@ cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Ud cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1 h1:vpK6iQWv/2uUeFJth4/cBHsQAGjn1iIE6AAlxipRaA0= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= +cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/bigquery v1.32.0 h1:0OMQYCp03Ff9B5OeVY8GGUlOC99s93bjM+c5xS0H5gs= -cloud.google.com/go/bigquery v1.32.0/go.mod h1:hAfV1647X+/fGUqeVVdKW+HfYtT5UCjOZsuOydOSH4M= +cloud.google.com/go/bigquery v1.43.0 h1:u0fvz5ysJBe1jwUPI4LuPwAX+o+6fCUwf3ECeg6eDUQ= +cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0 h1:v/k9Eueb8aAJ0vZuxKMrgm6kPhCLZU9HxFU+AFDs9Uk= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/datacatalog v1.3.0 h1:3llKXv7cC1acsWjvWmG0NQQkYVSVgunMSfVk7h6zz8Q= -cloud.google.com/go/datacatalog v1.3.0/go.mod h1:g9svFY6tuR+j+hrTw3J2dNcmI0dzmSiyOzm8kpLq0a0= +cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/datacatalog v1.6.0 h1:xzXGAE2fAuMh+ksODKr9nRv9ega1vHjFwRqMA8tRrVE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= -cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= +cloud.google.com/go/iam v0.5.0 h1:fz9X5zyTWBmamZsqvqZqD7khbifcZF/q+Z1J8pfhIUg= +cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= @@ -66,6 +63,8 @@ cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+ cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= +cloud.google.com/go/pubsub v1.26.0 h1:Y/HcMxVXgkUV2pYeLMUkclMg0ue6U0jVyI5xEARQ4zA= +cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= cloud.google.com/go/secretmanager v1.3.0/go.mod h1:+oLTkouyiYiabAQNugCeTS3PAArGiMJuBqvJnJsyH+U= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= @@ -73,10 +72,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= -cloud.google.com/go/storage v1.22.0/go.mod h1:GbaLEoMqbVm6sx3Z0R++gSiBlgMv6yUi2q1DeGFKQgE= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.25.0 h1:D2Dn0PslpK7Z3B2AvuUHyIC762bDbGJdlmQlCBR71os= -cloud.google.com/go/storage v1.25.0/go.mod h1:Qys4JU+jeup3QnuKKAosWuxrD95C4MSqxfVDnSirDsI= +cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= +cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= @@ -168,8 +165,8 @@ github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHf github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= -github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 h1:tXKVfhE7FcSkhkv0UwkLvPDeZ4kz6OXd0PKPlFqf81M= -github.com/bradleyfalzon/ghinstallation/v2 v2.0.4/go.mod h1:B40qPqJxWE0jDZgOR1JmaMy+4AY1eBP+IByOvqyAKp0= +github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 h1:5+NghM1Zred9Z078QEZtm28G/kfDfZN/92gkDlLwGVA= +github.com/bradleyfalzon/ghinstallation/v2 v2.1.0/go.mod h1:Xg3xPRN5Mcq6GDqeUVhFbjEWMb4JHCyWEeeBGEYQoTU= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= @@ -185,7 +182,6 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= @@ -209,7 +205,6 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= @@ -299,10 +294,13 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg= -github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg= +github.com/google/go-github/v38 v38.1.0 h1:C6h1FkaITcBFK7gAmq4eFzt6gbhEhk7L5z6R3Uva+po= +github.com/google/go-github/v38 v38.1.0/go.mod h1:cStvrz/7nFr0FoENgG6GLbp53WaelXucT+BBz/3VKx4= +github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI= +github.com/google/go-github/v45 v45.2.0/go.mod h1:FObaZJEDSTa/WGCzZ2Z3eoCDXWJKMenWWTrd8jrta28= github.com/google/go-github/v47 v47.1.0 h1:Cacm/WxQBOa9lF0FT0EMjZ2BWMetQ1TQfyurn4yF1z8= github.com/google/go-github/v47 v47.1.0/go.mod h1:VPZBXNbFSJGjyjFRUKo9vZGawTajnWzC/YjGw/oFKi0= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= github.com/google/go-replayers/grpcreplay v1.1.0 h1:S5+I3zYyZ+GQz68OfbURDdt/+cSMqCK1wrvNx7WBzTE= @@ -341,18 +339,15 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0 h1:zO8WHNx/MYiAKJ3d5spxZXZE6KHmIQGQcAzwUzV7qQw= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= +github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= +github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= @@ -410,6 +405,8 @@ github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqx github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= +github.com/jszwec/csvutil v1.7.1 h1:btxPxFwms8lHMgl0OIgOQ4Tayfqo0xid0hGkq1kM510= +github.com/jszwec/csvutil v1.7.1/go.mod h1:Rpu7Uu9giO9subDyMCIQfHVDuLrcaC36UA4YcJjGBkg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= @@ -417,8 +414,9 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= +github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= @@ -444,9 +442,12 @@ github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4 h1:Db6m7J/xaItRxVbesKIXwngw+Tr1IERv/LCnRBzhHvk= -github.com/ossf/scorecard/v4 v4.1.1-0.20220413163106-b00b31646ab4/go.mod h1:PbooSR+65A6HA+eoJ7ICwek/muANHZsR08QV24tuiKA= +github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa h1:+JsZaqE07NHU7nnXlNxiODY1W1Z/uY+THUww4QAzzW0= +github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa/go.mod h1:/6X5Q0wvCvWx/K1nyPWXzL2ZG3ZESBhP6okDFyXzcT0= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -455,6 +456,9 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= +github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= +github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= @@ -467,8 +471,9 @@ github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1 github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= +github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= +github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -540,8 +545,8 @@ golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5y golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e h1:T8NU3HyQ8ClP4SEE+KbFlg6n0NhuTsN4MyznaarGsZM= -golang.org/x/crypto v0.0.0-20220525230936-793ad666bf5e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -622,12 +627,8 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -648,10 +649,8 @@ golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 h1:+jnHzr9VPj32ykQVai5DNahi9+NSp7yYuCsl5eAQtL0= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= +golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -663,7 +662,8 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -734,14 +734,9 @@ golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f h1:v4INt8xihDGvnrfjMDVXGxw9wrfxYyCjk0KbXjhR55s= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -753,8 +748,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -824,10 +820,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f h1:uF6paiQQebLeSXkrTqHqz0MXhXXS1KgF41eUdBNvxK0= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= +golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -870,12 +864,8 @@ google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7 google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.88.0 h1:MPwxQRqpyskYhr2iNyfsQ8R06eeyhe7UEuR30p136ZQ= -google.golang.org/api v0.88.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.99.0 h1:tsBtOIklCE2OFxhmcYSVqGwSAN/Y897srxmcvAQnwK8= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -923,7 +913,6 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= @@ -967,21 +956,8 @@ google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2 google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220405205423-9d709892a2bf/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220720214146-176da50484ac h1:EOa+Yrhx1C0O+4pHeXeWrCwdI0tWI6IfUU56Vebs9wQ= -google.golang.org/genproto v0.0.0-20220720214146-176da50484ac/go.mod h1:GkXuJDJ6aQ7lnJcRF+SJVgFdQhypqgl3LB1C9vabdRE= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b h1:IOQ/4u8ZSLV+xns0LQxzdAcdOJTDMWB+0shVM8KWXBE= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1010,11 +986,8 @@ google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9K google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= @@ -1029,8 +1002,9 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.0 h1:w43yiav+6bVFTBQFZX0r7ipe9JQ1QsbMgHwbBziscLw= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= diff --git a/go.work.sum b/go.work.sum index 88a602de..4716b5fb 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,16 +1,39 @@ +cloud.google.com/go/monitoring v1.4.0 h1:05+IuNMbh40hbxcqQ4SnynbwZbLG1Wc9dysIJxnfv7U= +cloud.google.com/go/pubsub v1.20.0 h1:QuwfH5BpEIE9T3n0YK3PKlsXi/TmHMu593UpOVlWygI= +cloud.google.com/go/trace v1.2.0 h1:oIaB4KahkIUOpLSAAjEJ8y2desbjY/x/RfP4O3KAtTI= +contrib.go.opencensus.io/exporter/stackdriver v0.13.11 h1:YzmWJ2OT2K3ouXyMm5FmFQPoDs5TfLjx6Xn5x5CLN0I= +contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY= +github.com/caarlos0/env/v6 v6.9.1 h1:zOkkjM0F6ltnQ5eBX6IPI41UP/KDGEK7rRPwGCNos8k= +github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/google/go-github/v38 v38.1.0 h1:C6h1FkaITcBFK7gAmq4eFzt6gbhEhk7L5z6R3Uva+po= +github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jszwec/csvutil v1.6.0 h1:QORXquCT0t8nUKD7utAD4HDmQMgG0Ir9WieZXzpa7ms= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/moby/buildkit v0.8.3 h1:vFlwUQ6BZE1loZ8zoZH3fYgmA1djFCS3DrOhCVU6ZZE= +github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= +github.com/rhysd/actionlint v1.6.11 h1:8aD7ozc43RbnKwUmFvRtfW0LTW6f13MTXFDlf+0PNAc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= +gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +mvdan.cc/sh/v3 v3.4.3 h1:zbuKH7YH9cqU6PGajhFFXZY7dhPXcDr55iN/cUAqpuw= diff --git a/internal/collector/collector.go b/internal/collector/collector.go index 2d43ba4d..b636c799 100644 --- a/internal/collector/collector.go +++ b/internal/collector/collector.go @@ -48,7 +48,7 @@ var ErrRepoNotFound = fmt.Errorf("%w: not found", ErrUncollectableRepo) var ErrUnsupportedURL = fmt.Errorf("%w: unsupported url", ErrUncollectableRepo) type Collector struct { - config *Config + config *config logger *zap.Logger resolver *projectrepo.Resolver registry *registry diff --git a/internal/collector/config.go b/internal/collector/config.go index 4b4fc300..aa9dc1f6 100644 --- a/internal/collector/config.go +++ b/internal/collector/config.go @@ -65,7 +65,7 @@ const ( ) //nolint:govet -type Config struct { +type config struct { logger *zap.Logger gitHubHTTPClient *http.Client @@ -78,16 +78,16 @@ type Config struct { } // Option is an interface used to change the config. -type Option interface{ set(*Config) } +type Option interface{ set(*config) } // option implements Option interface. -type option func(*Config) +type option func(*config) // set implements the Option interface. -func (o option) set(c *Config) { o(c) } +func (o option) set(c *config) { o(c) } -func makeConfig(ctx context.Context, logger *zap.Logger, opts ...Option) *Config { - c := &Config{ +func makeConfig(ctx context.Context, logger *zap.Logger, opts ...Option) *config { + c := &config{ logger: logger, defaultSourceStatus: sourceStatusEnabled, sourceStatuses: make(map[SourceType]sourceStatus), @@ -104,7 +104,7 @@ func makeConfig(ctx context.Context, logger *zap.Logger, opts ...Option) *Config } // IsEnabled returns true if the given SourceType is enabled. -func (c *Config) IsEnabled(s SourceType) bool { +func (c *config) IsEnabled(s SourceType) bool { if status, ok := c.sourceStatuses[s]; ok { return status == sourceStatusEnabled } else { @@ -130,7 +130,7 @@ func defaultGitHubHTTPClient(ctx context.Context, logger *zap.Logger) *http.Clie // All data sources will be used for collection unless explicitly disabled // with DisableSource. func EnableAllSources() Option { - return option(func(c *Config) { + return option(func(c *config) { c.defaultSourceStatus = sourceStatusEnabled }) } @@ -140,21 +140,21 @@ func EnableAllSources() Option { // No data sources will be used for collection unless explicitly enabled // with EnableSource. func DisableAllSources() Option { - return option(func(c *Config) { + return option(func(c *config) { c.defaultSourceStatus = sourceStatusDisabled }) } // EnableSource will enable the supplied SourceType for collection. func EnableSource(s SourceType) Option { - return option(func(c *Config) { + return option(func(c *config) { c.sourceStatuses[s] = sourceStatusEnabled }) } // DisableSource will enable the supplied SourceType for collection. func DisableSource(s SourceType) Option { - return option(func(c *Config) { + return option(func(c *config) { c.sourceStatuses[s] = sourceStatusDisabled }) } @@ -164,14 +164,14 @@ func DisableSource(s SourceType) Option { // // If not supplied, the currently configured project will be used. func GCPProject(n string) Option { - return option(func(c *Config) { + return option(func(c *config) { c.gcpProject = n }) } // GCPDatasetName overrides DefaultGCPDatasetName with the supplied dataset name. func GCPDatasetName(n string) Option { - return option(func(c *Config) { + return option(func(c *config) { c.gcpDatasetName = n }) } diff --git a/internal/collector/config_test.go b/internal/collector/config_test.go index 8a22d0ff..f9e74631 100644 --- a/internal/collector/config_test.go +++ b/internal/collector/config_test.go @@ -80,7 +80,7 @@ func TestGCPDatasetName(t *testing.T) { } } -func makeTestConfig(t *testing.T, opts ...Option) *Config { +func makeTestConfig(t *testing.T, opts ...Option) *config { t.Helper() return makeConfig(context.Background(), zaptest.NewLogger(t), opts...) } From 9c9e74756ee516b696b4d55ec1370fb2ddcbc4ac Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 8 Nov 2022 17:07:51 +1100 Subject: [PATCH 120/172] Add marker file support to enumerate_github (#231) This change adds support for outputing a file containing the transformed output filename that the data is contained within. This marker file allows another script to quickly identify the latest enumeration. Additional changes: * Fix a bug where the bucket was returned instead of the full path. * Fix lint errors and other minor issues. * Add marker config to K8S and Docker compose. * Fix some incorrect usage of e vs err. Signed-off-by: Caleb Brown --- cmd/enumerate_github/main.go | 39 ++++++++ infra/k8s/enumerate_github.yaml | 2 + infra/test/docker-compose.yml | 1 + internal/cloudstorage/cloudstorage.go | 81 ++++++++++++++++ internal/cloudstorage/cloudstorage_test.go | 108 +++++++++++++++++++++ internal/outfile/outfile.go | 3 +- 6 files changed, 233 insertions(+), 1 deletion(-) create mode 100644 internal/cloudstorage/cloudstorage.go create mode 100644 internal/cloudstorage/cloudstorage_test.go diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 8acf05cc..355f241d 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -34,6 +34,7 @@ import ( "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" "github.com/ossf/criticality_score/cmd/enumerate_github/repowriter" + "github.com/ossf/criticality_score/internal/cloudstorage" "github.com/ossf/criticality_score/internal/envflag" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" @@ -54,6 +55,7 @@ var ( epochDate = time.Date(2008, 1, 1, 0, 0, 0, 0, time.UTC) runID = time.Now().UTC().Format(runIDDateFormat) + markerFileFlag = flag.String("marker", "", "writes the path to the file where results were written.") minStarsFlag = flag.Int("min-stars", 10, "only enumerates repositories with this or more of stars.") starOverlapFlag = flag.Int("star-overlap", 5, "the number of stars to overlap between queries.") requireMinStarsFlag = flag.Bool("require-min-stars", false, "abort if -min-stars can't be reached during enumeration.") @@ -75,6 +77,7 @@ var ( "CRITICALITY_SCORE_END_DATE": "end", "CRITICALITY_SCORE_OUTFILE": "out", "CRITICALITY_SCORE_OUTFILE_FORCE": "force", + "CRITICALITY_SCORE_MARKER": "marker", "CRITICALITY_SCORE_QUERY": "query", "CRITICALITY_SCORE_STARS_MIN": "min-stars", "CRITICALITY_SCORE_STARS_OVERLAP": "star-overlap", @@ -151,6 +154,26 @@ func searchWorker(s *githubsearch.Searcher, logger *zap.Logger, queries, results } } +func writeMarker(ctx context.Context, markerFile, outFile string) (err error) { + marker, e := cloudstorage.NewWriter(ctx, markerFile) + if e != nil { + return fmt.Errorf("open marker: %w", e) + } + defer func() { + if e := marker.Close(); e != nil { + // Return the error using the named return value if it isn't + // already set. + if e == nil { + err = fmt.Errorf("closing marker: %w", e) + } + } + }() + if _, e := fmt.Fprintln(marker, outFile); e != nil { + err = fmt.Errorf("writing marker: %w", e) + } + return +} + func main() { envflag.Parse(envFlagMap) @@ -262,6 +285,22 @@ func main() { // Wait for the writer to be finished. <-done + // Trigger Close() early to ensure the data exists before the marker file. + if err := out.Close(); err != nil { + logger.Fatal("Failed write data", zap.Error(err)) + } + + if *markerFileFlag != "" { + logger = logger.With(zap.String("marker_filename", *markerFileFlag)) + logger.Debug("Writing the marker file") + + if err := writeMarker(ctx, *markerFileFlag, out.Name()); err != nil { + logger.Error("Failed creating marker file", zap.Error(err)) + // Don't exit after a failure to create the marker file. Just fail + // to write the marker file. + } + } + logger.With( zap.Int("total_repos", totalRepos), zap.Duration("duration", time.Since(startTime).Truncate(time.Minute)), diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml index 157add66..1c28cd65 100644 --- a/infra/k8s/enumerate_github.yaml +++ b/infra/k8s/enumerate_github.yaml @@ -37,6 +37,8 @@ spec: value: "gs://ossf-criticality-score-url-data/[[runid]]/github.csv" - name: CRITICALITY_SCORE_OUTFILE_FORCE value: "1" + - name: CRITICALITY_SCORE_MARKER + value: "gs://ossf-criticality-score-url-data/latest" - name: CRITICALITY_SCORE_STARS_MIN value: "20" - name: CRITICALITY_SCORE_START_DATE diff --git a/infra/test/docker-compose.yml b/infra/test/docker-compose.yml index 7d0df96e..9369efec 100644 --- a/infra/test/docker-compose.yml +++ b/infra/test/docker-compose.yml @@ -48,6 +48,7 @@ services: CRITICALITY_SCORE_STARS_MIN: ${CRITICALITY_SCORE_STARS_MIN:-100} CRITICALITY_SCORE_START_DATE: ${CRITICALITY_SCORE_START_DATE} CRITICALITY_SCORE_END_DATE: ${CRITICALITY_SCORE_END_DATE} + CRITICALITY_SCORE_MARKER: s3://criticality_score/enumeration/latest.txt?endpoint=minio:9000&disableSSL=true&s3ForcePathStyle=true GITHUB_AUTH_SERVER: auth:8080 AWS_ACCESS_KEY_ID: minio AWS_SECRET_ACCESS_KEY: minio123 diff --git a/internal/cloudstorage/cloudstorage.go b/internal/cloudstorage/cloudstorage.go new file mode 100644 index 00000000..6f635c23 --- /dev/null +++ b/internal/cloudstorage/cloudstorage.go @@ -0,0 +1,81 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package cloudstorage + +import ( + "context" + "fmt" + "io" + "net/url" + "path" + "strings" + + "gocloud.dev/blob" + _ "gocloud.dev/blob/fileblob" + _ "gocloud.dev/blob/gcsblob" + _ "gocloud.dev/blob/memblob" + _ "gocloud.dev/blob/s3blob" +) + +func parseBucketAndPrefix(rawURL string) (bucket, prefix string, _ error) { + u, err := url.Parse(rawURL) + if err != nil { + return "", "", fmt.Errorf("url parse: %w", err) + } + + // If the URL doesn't have a scheme it is possibly a local file. Use the + // fileblob storage to handle these files because the behavior is + // more consistent with cloud storage services - in particular + // atomic updates, and read-after-write consistency. + if !u.IsAbs() { + // If the Host is set (e.g. //example.com/) then we have a problem. + if u.Host != "" { + return "", "", fmt.Errorf("undefined blob scheme: %s", u.String()) + } + + // Assume a scheme-less, host-less url is a local file. + u.Scheme = "file" + if !path.IsAbs(u.Path) { + u.Host = "." + } + // Turn off .attrs files, becaue they look weird next to local files. + q := u.Query() + q.Set("metadata", "skip") + u.RawQuery = q.Encode() + } + + // gocloud.dev expects prefix/key and bucket to be separate values. + prefix = strings.TrimPrefix(u.Path, "/") + u.Path = "" + bucket = u.String() + return bucket, prefix, nil +} + +func NewWriter(ctx context.Context, rawURL string) (io.WriteCloser, error) { + bucket, prefix, err := parseBucketAndPrefix(rawURL) + if err != nil { + return nil, err + } + + b, err := blob.OpenBucket(ctx, bucket) + if err != nil { + return nil, fmt.Errorf("failed to opening %s: %w", bucket, err) + } + w, err := b.NewWriter(ctx, prefix, nil) + if err != nil { + return nil, fmt.Errorf("failed creating writer for %s: %w", rawURL, err) + } + return w, nil +} diff --git a/internal/cloudstorage/cloudstorage_test.go b/internal/cloudstorage/cloudstorage_test.go new file mode 100644 index 00000000..16d6298b --- /dev/null +++ b/internal/cloudstorage/cloudstorage_test.go @@ -0,0 +1,108 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +//nolint:goconst +package cloudstorage + +import ( + "context" + "net/url" + "testing" +) + +func TestParseBucketAndPrefixAbsLocalFile(t *testing.T) { + b, p, err := parseBucketAndPrefix("/path/to/file") + if err != nil { + t.Fatalf("parseBucketAndPrefix() = %v, want no error", err) + } + assertBucket(t, b, "file", "", map[string]string{"metadata": "skip"}) + if p != "path/to/file" { + t.Fatalf("Prefix = %v; want path/to/file", p) + } +} + +func TestParseBucketAndPrefixRelativeLocalFile(t *testing.T) { + b, p, err := parseBucketAndPrefix("path/to/file") + if err != nil { + t.Fatalf("parseBucketAndPrefix() = %v, want no error", err) + } + assertBucket(t, b, "file", ".", map[string]string{"metadata": "skip"}) + if p != "path/to/file" { + t.Fatalf("Prefix = %v; want path/to/file", p) + } +} + +func TestParseBucketAndPrefixS3URL(t *testing.T) { + b, p, err := parseBucketAndPrefix("s3://bucket/path/to/file") + if err != nil { + t.Fatalf("parseBucketAndPrefix() = %v, want no error", err) + } + assertBucket(t, b, "s3", "bucket", map[string]string{}) + if p != "path/to/file" { + t.Fatalf("Prefix = %v; want path/to/file", p) + } +} + +func TestNewWriterNoScheme(t *testing.T) { + _, _, err := parseBucketAndPrefix("//example.com/path/to/file") + if err == nil { + t.Fatal("parseBucketAndPrefix() = nil; want an error") + } +} + +func TestNewWriterInvalidURL(t *testing.T) { + _, err := NewWriter(context.Background(), "::") + if err == nil { + t.Fatal("NewWriter() = nil; want an error") + } +} + +func TestNewWriterUnsupportedScheme(t *testing.T) { + _, err := NewWriter(context.Background(), "ftp://bucket/path/to/file") + if err == nil { + t.Fatal("NewWriter() = nil; want an error") + } +} + +func TestNewWriter(t *testing.T) { + w, err := NewWriter(context.Background(), "mem://bucket/path/to/file") + if err != nil { + t.Fatalf("NewWriter() = %v, want no error", err) + } + if w == nil { + t.Fatal("NewWriter() = nil, want a writer") + } +} + +func assertBucket(t *testing.T, bucket, wantScheme, wantHost string, wantQuery map[string]string) { + t.Helper() + u, err := url.Parse(bucket) + if err != nil { + t.Fatalf("Bucket is not a valid url: %v", err) + } + if u.Scheme != wantScheme { + t.Fatalf("Bucket scheme = %q, want %q", u.Scheme, wantScheme) + } + if u.Host != wantHost { + t.Fatalf("Bucket host = %q, want %q", u.Scheme, wantHost) + } + for k, want := range wantQuery { + if !u.Query().Has(k) { + t.Fatalf("Bucket query has no key %q", k) + } + if got := u.Query().Get(k); got != want { + t.Fatalf("Bucket query %q = %q, want %q", k, got, want) + } + } +} diff --git a/internal/outfile/outfile.go b/internal/outfile/outfile.go index 32946215..2fd0c3af 100644 --- a/internal/outfile/outfile.go +++ b/internal/outfile/outfile.go @@ -90,6 +90,7 @@ func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (NameWriteCloser if o.append || !o.force { return nil, fmt.Errorf("blob store must use -%s flag", o.forceFlag) } + name := u.String() // Separate the path from the URL as options may be present in the query // string. @@ -107,7 +108,7 @@ func (o *Opener) openBlobStore(ctx context.Context, u *url.URL) (NameWriteCloser } return &writeCloserWrapper{ WriteCloser: w, - name: u.String(), + name: name, }, nil } From af1ea4f51bc362d27ee2f76d1d573264898c4687 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 17:21:09 +1100 Subject: [PATCH 121/172] Bump gocloud.dev from 0.26.0 to 0.27.0 (#209) Bumps [gocloud.dev](https://github.com/google/go-cloud) from 0.26.0 to 0.27.0. - [Release notes](https://github.com/google/go-cloud/releases) - [Commits](https://github.com/google/go-cloud/compare/v0.26.0...v0.27.0) --- updated-dependencies: - dependency-name: gocloud.dev dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 42 +- go.sum | 1469 ++++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 1385 insertions(+), 126 deletions(-) diff --git a/go.mod b/go.mod index 902b0144..d776de8c 100644 --- a/go.mod +++ b/go.mod @@ -12,7 +12,7 @@ require ( github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 go.uber.org/zap v1.23.0 - gocloud.dev v0.26.0 + gocloud.dev v0.27.0 google.golang.org/api v0.99.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -23,29 +23,30 @@ require ( cloud.google.com/go/iam v0.5.0 // indirect cloud.google.com/go/pubsub v1.26.0 // indirect cloud.google.com/go/storage v1.27.0 // indirect - github.com/aws/aws-sdk-go v1.43.31 // indirect - github.com/aws/aws-sdk-go-v2 v1.16.2 // indirect - github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 // indirect - github.com/aws/aws-sdk-go-v2/config v1.15.3 // indirect - github.com/aws/aws-sdk-go-v2/credentials v1.11.2 // indirect - github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 // indirect - github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 // indirect - github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 // indirect - github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 // indirect - github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 // indirect - github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 // indirect - github.com/aws/smithy-go v1.11.2 // indirect + github.com/aws/aws-sdk-go v1.44.68 // indirect + github.com/aws/aws-sdk-go-v2 v1.16.8 // indirect + github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 // indirect + github.com/aws/aws-sdk-go-v2/config v1.15.15 // indirect + github.com/aws/aws-sdk-go-v2/credentials v1.12.10 // indirect + github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9 // indirect + github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21 // indirect + github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15 // indirect + github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9 // indirect + github.com/aws/aws-sdk-go-v2/internal/ini v1.3.16 // indirect + github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.9 // indirect + github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2 // indirect + github.com/aws/aws-sdk-go-v2/service/sso v1.11.13 // indirect + github.com/aws/aws-sdk-go-v2/service/sts v1.16.10 // indirect + github.com/aws/smithy-go v1.12.0 // indirect github.com/benbjohnson/clock v1.1.0 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 // indirect github.com/go-logr/logr v1.2.3 // indirect - github.com/golang-jwt/jwt/v4 v4.4.1 // indirect + github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.2 // indirect github.com/google/go-github/v38 v38.1.0 // indirect @@ -57,7 +58,6 @@ require ( github.com/googleapis/gax-go/v2 v2.6.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jszwec/csvutil v1.7.1 // indirect - github.com/kr/pretty v0.3.0 // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect github.com/sirupsen/logrus v1.9.0 // indirect diff --git a/go.sum b/go.sum index d004dd10..22d583de 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,5 @@ +bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= +bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -29,6 +31,9 @@ cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Ud cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= +cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= +cloud.google.com/go v0.103.0/go.mod h1:vwLx1nqLrzLX/fpwSMOXmFIqBOyHsvHbnAdbGSJ+mKk= cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -40,140 +45,267 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/bigquery v1.43.0 h1:u0fvz5ysJBe1jwUPI4LuPwAX+o+6fCUwf3ECeg6eDUQ= cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= -cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= +cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= +cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= cloud.google.com/go/datacatalog v1.6.0 h1:xzXGAE2fAuMh+ksODKr9nRv9ega1vHjFwRqMA8tRrVE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= -cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0 h1:fz9X5zyTWBmamZsqvqZqD7khbifcZF/q+Z1J8pfhIUg= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= -cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= -cloud.google.com/go/monitoring v1.4.0/go.mod h1:y6xnxfwI3hTFWOdkOaD7nfJVlwuC3/mS/5kvtT131p4= +cloud.google.com/go/monitoring v1.5.0/go.mod h1:/o9y8NYX5j91JjD/JvGLYbi86kL11OjyJXq2XziLJu4= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= +cloud.google.com/go/pubsub v1.24.0/go.mod h1:rWv09Te1SsRpRGPiWOMDKraMQTJyJps4MkUCoMGUgqw= cloud.google.com/go/pubsub v1.26.0 h1:Y/HcMxVXgkUV2pYeLMUkclMg0ue6U0jVyI5xEARQ4zA= cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/secretmanager v1.3.0/go.mod h1:+oLTkouyiYiabAQNugCeTS3PAArGiMJuBqvJnJsyH+U= +cloud.google.com/go/secretmanager v1.5.0/go.mod h1:5C9kM+RwSpkURNovKySkNvGQLUaOgyoR5W0RUx2SyHQ= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= +cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= +cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= +cloud.google.com/go/storage v1.24.0/go.mod h1:3xrJEFMXBsQLgxwThyjuD3aYlroL0TMRec1ypGUQ0KE= cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= +code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= -contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= +contrib.go.opencensus.io/exporter/stackdriver v0.13.13/go.mod h1:5pSSGY0Bhuk7waTHuDf4aQ8D2DrhgETRo9fy6k3Xlzc= contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= -github.com/Azure/azure-amqp-common-go/v3 v3.2.2/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= -github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= -github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= -github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v59.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= +github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= +github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v63.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v66.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= +github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= -github.com/Azure/azure-service-bus-go v0.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= -github.com/Azure/azure-storage-blob-go v0.14.0 h1:1BCg74AmVdYwO3dlKwtFU1V0wU2PZdREkXvAmZJRUlM= -github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= -github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= -github.com/Azure/go-amqp v0.16.4/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= +github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.0.2/go.mod h1:LH9XQnMr2ZYxQdVdCrzLO9mxeDyrDFa6wbSI3x5zCZk= +github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1/go.mod h1:eZ4g6GUvXiGulfIbbhh1Xr4XwUYaYaWMqzGD/284wCA= +github.com/Azure/go-amqp v0.17.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-amqp v0.17.5/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= +github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= +github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= +github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= +github.com/Azure/go-autorest/autorest v0.11.25/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= +github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= +github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= +github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.17/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.9/go.mod h1:hg3/1yw0Bq87O3KvvnJoAh34/0zbP7SFizX/qN5JvjU= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= +github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.11/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= +github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= +github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= +github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= +github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= +github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.31.2/go.mod h1:qR6jVnZTKDCW3j+fC9mOEPHm++1nKDMkqbbkD6KNsfo= +github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= +github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= +github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= +github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= +github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= +github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= +github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= +github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= +github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= +github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= +github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= +github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= +github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= +github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= +github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= +github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= +github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= +github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= +github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= +github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= +github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= +github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= +github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= +github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= +github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= +github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= +github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= +github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= +github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= +github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= +github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= +github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.43.31 h1:yJZIr8nMV1hXjAvvOLUFqZRJcHV7udPQBfhJqawDzI0= +github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= +github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go-v2 v1.16.2 h1:fqlCk6Iy3bnCumtrLz9r3mJ/2gUT0pJ0wLFVIdWh+JA= -github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1 h1:SdK4Ppk5IzLs64ZMvr6MrSficMtjY2oS0WOORXTlxwU= -github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM= -github.com/aws/aws-sdk-go-v2/config v1.15.3 h1:5AlQD0jhVXlGzwo+VORKiUuogkG7pQcLJNzIzK7eodw= -github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= -github.com/aws/aws-sdk-go-v2/credentials v1.11.2 h1:RQQ5fzclAKJyY5TvF+fkjJEwzK4hnxQCLOu5JXzDmQo= -github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3 h1:LWPg5zjHV9oz/myQr4wMs0gi4CjnDN/ILmyZUFYXZsU= -github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3 h1:ir7iEq78s4txFGgwcLqD6q9IIPzTQNRJXulJd9h/zQo= -github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3/go.mod h1:0dHuD2HZZSiwfJSy1FO5bX1hQ1TxVV1QXXjpn3XUE44= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9 h1:onz/VaaxZ7Z4V+WIN9Txly9XLTmoOh1oJ8XcAC3pako= -github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3 h1:9stUQR/u2KXU6HkFJYlqnZEjBnbgrVbG6I5HN09xZh0= -github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10 h1:by9P+oy3P/CwggN4ClnW2D4oL91QV7pBzBICi1chZvQ= -github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1 h1:T4pFel53bkHjL2mMo+4DKE6r6AuoZnM0fg7k1/ratr4= -github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3 h1:I0dcwWitE752hVSMrsLCxqNQ+UdEp3nACx2bYNMQq+k= -github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3 h1:Gh1Gpyh01Yvn7ilO/b/hr01WgNpaszfbKMUgqM186xQ= -github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3 h1:BKjwCJPnANbkwQ8vzSbaZDKawwagDubrH/z/c0X+kbQ= -github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3/go.mod h1:Bm/v2IaN6rZ+Op7zX+bOUMdL4fsrYZiD0dsjLhNKwZc= -github.com/aws/aws-sdk-go-v2/service/kms v1.16.3/go.mod h1:QuiHPBqlOFCi4LqdSskYYAWpQlx3PKmohy+rE2F+o5g= -github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3 h1:rMPtwA7zzkSQZhhz9U3/SoIDz/NZ7Q+iRn4EIO8rSyU= -github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3/go.mod h1:g1qvDuRsJY+XghsV6zg00Z4KJ7DtFFCx8fJD2a491Ak= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4/go.mod h1:PJc8s+lxyU8rrre0/4a0pn2wgwiDvOEzoOjcJUBr67o= -github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw= -github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3/go.mod h1:skmQo0UPvsjsuYYSYMVmrPc1HWCbHUJyrCEp+ZaLzqM= -github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1/go.mod h1:NR/xoKjdbRJ+qx0pMR4mI+N/H1I1ynHwXnO6FowXJc0= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.3 h1:frW4ikGcxfAEDfmQqWgMLp+F1n4nRo9sF39OcIb5BkQ= -github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.3 h1:cJGRyzCSVwZC7zZZ1xbx9m32UnrKydRYhOvcD1NYP9Q= -github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= -github.com/aws/smithy-go v1.11.2 h1:eG/N+CcUMAvsdffgMvjMKwfyDzIkjM6pfxMJ8Mzc6mE= -github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= +github.com/aws/aws-sdk-go v1.44.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.44.68 h1:7zNr5+HLG0TMq+ZcZ8KhT4eT2KyL7v+u7/jANKEIinM= +github.com/aws/aws-sdk-go v1.44.68/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.16.8 h1:gOe9UPR98XSf7oEJCcojYg+N2/jCRm4DdeIsP85pIyQ= +github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 h1:S/ZBwevQkr7gv5YxONYpGQxlMFFYSRfz3RMcjsC9Qhk= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y= +github.com/aws/aws-sdk-go-v2/config v1.15.15 h1:yBV+J7Au5KZwOIrIYhYkTGJbifZPCkAnCFSvGsF3ui8= +github.com/aws/aws-sdk-go-v2/config v1.15.15/go.mod h1:A1Lzyy/o21I5/s2FbyX5AevQfSVXpvvIDCoVFD0BC4E= +github.com/aws/aws-sdk-go-v2/credentials v1.12.10 h1:7gGcMQePejwiKoDWjB9cWnpfVdnz/e5JwJFuT6OrroI= +github.com/aws/aws-sdk-go-v2/credentials v1.12.10/go.mod h1:g5eIM5XRs/OzIIK81QMBl+dAuDyoLN0VYaLP+tBqEOk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9 h1:hz8tc+OW17YqxyFFPSkvfSikbqWcyyHRyPVSTzC0+aI= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9/go.mod h1:KDCCm4ONIdHtUloDcFvK2+vshZvx4Zmj7UMDfusuz5s= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21 h1:bpiKFJ9aC0xTVpygSRRRL/YHC1JZ+pHQHENATHuoiwo= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21/go.mod h1:iIYPrQ2rYfZiB/iADYlhj9HHZ9TTi6PqKQPAqygohbE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15 h1:bx5F2mr6H6FC7zNIQoDoUr8wEKnvmwRncujT3FYRtic= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9 h1:5sbyznZC2TeFpa4fvtpvpcGbzeXEEs1l1Jo51ynUNsQ= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9/go.mod h1:08tUpeSGN33QKSO7fwxXczNfiwCpbj+GxK6XKwqWVv0= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.16 h1:f0ySVcmQhwmzn7zQozd8wBM3yuGBfzdpsOaKQ0/Epzw= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.16/go.mod h1:CYmI+7x03jjJih8kBEEFKRQc40UjUokT0k7GbvrhhTc= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6 h1:3L8pcjvgaSOs0zzZcMKzxDSkYKEpwJ2dNVDdxm68jAY= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6/go.mod h1:O7Oc4peGZDEKlddivslfYFvAbgzvl/GH3J8j3JIGBXc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 h1:4n4KCtv5SUoT5Er5XV41huuzrCqepxlW3SDI9qHQebc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3/go.mod h1:gkb2qADY+OHaGLKNTYxMaQNacfeyQpZ4csDTQMeFmcw= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10 h1:7LJcuRalaLw+GYQTMGmVUl4opg2HrDZkvn/L3KvIQfw= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10/go.mod h1:Qks+dxK3O+Z2deAhNo6cJ8ls1bam3tUGUAcgxQP1c70= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.9 h1:sHfDuhbOuuWSIAEDd3pma6p0JgUcR2iePxtCE8gfCxQ= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.9/go.mod h1:yQowTpvdZkFVuHrLBXmczat4W+WJKg/PafBZnGBLga0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9 h1:sJdKvydGYDML9LTFcp6qq6Z5fIjN0Rdq2Gvw1hUg8tc= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9/go.mod h1:Rc5+wn2k8gFSi3V1Ch4mhxOzjMh+bYSXVFfVaqowQOY= +github.com/aws/aws-sdk-go-v2/service/kms v1.18.1/go.mod h1:4PZMUkc9rXHWGVB5J9vKaZy3D7Nai79ORworQ3ASMiM= +github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2 h1:NvzGue25jKnuAsh6yQ+TZ4ResMcnp49AWgWGm2L4b5o= +github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2/go.mod h1:u+566cosFI+d+motIz3USXEh6sN8Nq4GrNXSg2RXVMo= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.14/go.mod h1:xakbH8KMsQQKqzX87uyyzTHshc/0/Df8bsTneTS5pFU= +github.com/aws/aws-sdk-go-v2/service/sns v1.17.10/go.mod h1:uITsRNVMeCB3MkWpXxXw0eDz8pW4TYLzj+eyQtbhSxM= +github.com/aws/aws-sdk-go-v2/service/sqs v1.19.1/go.mod h1:A94o564Gj+Yn+7QO1eLFeI7UVv3riy/YBFOfICVqFvU= +github.com/aws/aws-sdk-go-v2/service/ssm v1.27.6/go.mod h1:fiFzQgj4xNOg4/wqmAiPvzgDMXPD+cUEplX/CYn+0j0= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.13 h1:DQpf+al+aWozOEmVEdml67qkVZ6vdtGUi71BZZWw40k= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.13/go.mod h1:d7ptRksDDgvXaUvxyHZ9SYh+iMDymm94JbVcgvSYSzU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.10 h1:7tquJrhjYz2EsCBvA9VTl+sBAAh1bv7h/sGASdZOGGo= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.10/go.mod h1:cftkHYN6tCDNfkSasAmclSfl4l7cySoay8vz7p/ce0E= +github.com/aws/smithy-go v1.12.0 h1:gXpeZel/jPoWQ7OEmLIgCUnhkFftqNfwWUwAHSlp1v0= +github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= +github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= +github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= +github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= +github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= +github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= +github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= +github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 h1:5+NghM1Zred9Z078QEZtm28G/kfDfZN/92gkDlLwGVA= github.com/bradleyfalzon/ghinstallation/v2 v2.1.0/go.mod h1:Xg3xPRN5Mcq6GDqeUVhFbjEWMb4JHCyWEeeBGEYQoTU= +github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= +github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= +github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= +github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= +github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= +github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= +github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= +github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= +github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= +github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= +github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= +github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= +github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= +github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= +github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= +github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= +github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= +github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= +github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -182,21 +314,186 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= +github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= +github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= +github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= +github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= +github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= +github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= +github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= +github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= +github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= +github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= +github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= +github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= +github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= +github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= +github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= +github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= +github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= +github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= +github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= +github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= +github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= +github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= +github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= +github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= +github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= +github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= +github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= +github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= +github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= +github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= +github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= +github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= +github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= +github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= +github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= +github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= +github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= +github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= +github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= +github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= +github.com/containerd/go-cni v1.1.3/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= +github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= +github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= +github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= +github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= +github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= +github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= +github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= +github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4= +github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= +github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= +github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= +github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= +github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= +github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= +github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= +github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= +github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= +github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= +github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= +github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= +github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= +github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= +github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= +github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= +github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= +github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= +github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= +github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= +github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= +github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= +github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= +github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= +github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= +github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= +github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= +github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= +github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= +github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= +github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= +github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= +github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= +github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= +github.com/denisenkom/go-mssqldb v0.12.2/go.mod h1:lnIw1mZukFRZDJYQ0Pb833QS2IaC3l5HkEfra2LJ+sk= +github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= +github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= -github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= +github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= +github.com/digitalocean/godo v1.78.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm0xbEVw2LCs= +github.com/digitalocean/godo v1.81.0/go.mod h1:BPCqvwbjbGqxuUnIKB4EvS/AX7IDnNmt5fwvIkWo+ew= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= +github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= +github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= +github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= +github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= +github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= +github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= +github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= +github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= +github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= +github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= +github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= +github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= +github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= +github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= +github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= +github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= +github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= +github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= +github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -205,44 +502,166 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= +github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= +github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= +github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= +github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= +github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= +github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= +github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= +github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= +github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= +github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= +github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= +github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= +github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= +github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= +github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= +github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= +github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= +github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= +github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= +github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= +github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= +github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= +github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= +github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= +github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= +github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= +github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= +github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= +github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= +github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= +github.com/go-openapi/runtime v0.23.1/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= +github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= +github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= +github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= +github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= +github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= +github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= +github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= +github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= +github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= +github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= +github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= +github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= +github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= +github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= +github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= +github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= +github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= +github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= +github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= +github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= +github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= +github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= +github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= +github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= +github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= +github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= +github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= +github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= +github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= +github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= +github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= +github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= +github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= +github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= +github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= +github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.4.1 h1:pC5DB52sCeK48Wlb9oPcdhnjkz1TKt1D/P7WKJ0kUcQ= +github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= +github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= +github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= +github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -275,9 +694,14 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= +github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -294,6 +718,7 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github/v38 v38.1.0 h1:C6h1FkaITcBFK7gAmq4eFzt6gbhEhk7L5z6R3Uva+po= github.com/google/go-github/v38 v38.1.0/go.mod h1:cStvrz/7nFr0FoENgG6GLbp53WaelXucT+BBz/3VKx4= github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI= @@ -308,6 +733,8 @@ github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6A github.com/google/go-replayers/httpreplay v1.1.1 h1:H91sIMlt1NZzN7R+/ASswyouLJfW0WLW7fhyUFvDEkY= github.com/google/go-replayers/httpreplay v1.1.1/go.mod h1:gN9GeLIs7l6NUoVaSSnv2RiqK1NiwAmD0MrKeC9IIks= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -331,14 +758,20 @@ github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20220318212150-b2ab0324ddda/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= +github.com/google/pprof v0.0.0-20220608213341-c488b8fa1db3/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= +github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= +github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= +github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -346,18 +779,109 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= +github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= +github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= +github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= +github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= +github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= +github.com/gophercloud/gophercloud v0.24.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= +github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= +github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= +github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grafana/regexp v0.0.0-20220304095617-2e8d9baf4ac2/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= +github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= +github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2/go.mod h1:chrfS3YoLAlKTRE5cFWvCbt8uGAjshktT4PveTUpsFQ= github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= github.com/hanwen/go-fuse/v2 v2.1.0/go.mod h1:oRyA5eK+pvJyv5otpO/DgccS8y/RvYMaO00GgRLGryc= +github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= +github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= +github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= +github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= +github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= +github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= +github.com/hashicorp/cronexpr v1.1.1/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= +github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= +github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= +github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= +github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= +github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= +github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= +github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= +github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= +github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= +github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= +github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= +github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= +github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= +github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= +github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= +github.com/hashicorp/nomad/api v0.0.0-20220629141207-c2428e1673ec/go.mod h1:jP79oXjopTyH6E8LF0CEMq67STgrlmBRIyijA0tuR5o= +github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= +github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= +github.com/hetznercloud/hcloud-go v1.33.1/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME= +github.com/hetznercloud/hcloud-go v1.35.0/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= +github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= +github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= +github.com/ionos-cloud/sdk-go/v6 v6.1.0/go.mod h1:Ox3W0iiEz0GHnfY9e5LmAxwklsxguuNFEUSu0gVRTME= +github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= +github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= @@ -367,7 +891,7 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= +github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= @@ -380,120 +904,503 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= +github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= +github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= +github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jszwec/csvutil v1.7.1 h1:btxPxFwms8lHMgl0OIgOQ4Tayfqo0xid0hGkq1kM510= github.com/jszwec/csvutil v1.7.1/go.mod h1:Rpu7Uu9giO9subDyMCIQfHVDuLrcaC36UA4YcJjGBkg= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= +github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= +github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= +github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= +github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= +github.com/linode/linodego v1.4.0/go.mod h1:PVsRxSlOiJyvG4/scTszpmZDTdgS+to3X6eS8pRrWI8= +github.com/linode/linodego v1.8.0/go.mod h1:heqhl91D8QTPVm2k9qZHP78zzbOdTFLXE9NJc3bcc50= +github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= +github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= +github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= +github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= +github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= +github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= +github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI= -github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= +github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= +github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= +github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= +github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= +github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= +github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= +github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U= +github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= +github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= +github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= +github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= +github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= +github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= +github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= +github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= +github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= +github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= +github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= +github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= +github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= +github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= +github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= +github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= +github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= +github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= +github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= +github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= +github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= +github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= +github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= +github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= +github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= +github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= +github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= +github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= +github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= +github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= +github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= +github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= +github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= +github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= +github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= +github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= +github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= +github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= +github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= +github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= +github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= +github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= +github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= +github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= +github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= +github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= +github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= +github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= +github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= +github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= +github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= +github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= +github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= +github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= +github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= +github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= +github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= +github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= +github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= +github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= +github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= +github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= +github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= +github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa h1:+JsZaqE07NHU7nnXlNxiODY1W1Z/uY+THUww4QAzzW0= github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa/go.mod h1:/6X5Q0wvCvWx/K1nyPWXzL2ZG3ZESBhP6okDFyXzcT0= +github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= +github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= +github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= +github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= +github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= +github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= +github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= +github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= +github.com/prometheus/alertmanager v0.24.0/go.mod h1:r6fy/D7FRuZh5YbnX6J3MBY0eI4Pb5yPYS7/bPSXXqI= +github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= +github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= +github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= +github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= +github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= +github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= +github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= +github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= +github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common/assets v0.1.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= +github.com/prometheus/common/assets v0.2.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= +github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= +github.com/prometheus/exporter-toolkit v0.7.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= +github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= +github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/prometheus v0.35.0/go.mod h1:7HaLx5kEPKJ0GDgbODG0fZgXbQ8K/XjZNJXQmbmgQlY= +github.com/prometheus/prometheus v0.37.0/go.mod h1:egARUgz+K93zwqsVIAneFlLZefyGOON44WyAp4Xqbbk= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rakyll/embedmd v0.0.0-20171029212350-c8060a0752a2/go.mod h1:7jOTMgqac46PZcF54q6l2hkLEG8op93fZu61KmxWDV4= +github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= +github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= +github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= +github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= +github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= +github.com/scaleway/scaleway-sdk-go v1.0.0-beta.9/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= +github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= +github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 h1:82EIpiGB79OIPgSGa63Oj4Ipf+YAX1c6A9qjmEYoRXc= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= +github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= +github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= +github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= +github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= +github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= +github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= +github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= +github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= +github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= +github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= +github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= +github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= +github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= +github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= +github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= +github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= +github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= +github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= +github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= +github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= +github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= +github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= +github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= +github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= +github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= +github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= +github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= +github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= +github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= +github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= +github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= +go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= +go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= +go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= +go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= +go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= +go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= +go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= +go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= +go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= +go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= +go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= +go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= +go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= +go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -502,7 +1409,50 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= +go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.31.0/go.mod h1:PFmBsWbldL1kiWZk9+0LBZz2brhByaGsvp6pRICMlPE= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= +go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= +go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= +go.opentelemetry.io/otel v1.6.0/go.mod h1:bfJD2DZVw0LBxghOTlgnlI0CV3hLDu9XF/QKOUXMTQQ= +go.opentelemetry.io/otel v1.6.1/go.mod h1:blzUabWHkX6LJewxvadmzafgh/wnvBSDBdOuwkAtrWQ= +go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= +go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.1/go.mod h1:NEu79Xo32iVb+0gVNV8PMd7GoWqnyDXRlj04yFjqz40= +go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.6.1/go.mod h1:YJ/JbY5ag/tSQFXzH3mtDmHqzF3aFn3DI/aB1n7pt4w= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.1/go.mod h1:UJJXJj0rltNIemDMwkOJyggsvyMG9QHfJeFH0HS5JjM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0/go.mod h1:E+/KKhwOSw8yoPxSSuUHG6vKppkvhN+S1Jc7Nib3k3o= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.6.1/go.mod h1:DAKwdo06hFLc0U88O10x4xnb5sc7dDRDqRuiN+io8JE= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0/go.mod h1:aFXT9Ng2seM9eizF+LfKiyPBGy8xIZKwhusC1gIu3hA= +go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= +go.opentelemetry.io/otel/metric v0.28.0/go.mod h1:TrzsfQAmQaB1PDcdhBauLMk7nyyg9hm+GoQq/ekE9Iw= +go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= +go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= +go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= +go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= +go.opentelemetry.io/otel/sdk v1.6.1/go.mod h1:IVYrddmFZ+eJqu2k38qD3WezFR2pymCzm8tdxyh3R4E= +go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= +go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= +go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= +go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= +go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= +go.opentelemetry.io/otel/trace v1.6.0/go.mod h1:qs7BrU5cZ8dXQHBGxHMOxwME/27YH2qEp4/+tZLLwJE= +go.opentelemetry.io/otel/trace v1.6.1/go.mod h1:RkFRM1m0puWIq10oxImnGEduNBzxiN7TXluRBtE+5j0= +go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= +go.opentelemetry.io/proto/otlp v0.12.1/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= +go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -510,9 +1460,11 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= -go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= +go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -523,28 +1475,45 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= +go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -gocloud.dev v0.26.0 h1:4rM/SVL0lLs+rhC0Gmc+gt/82DBpb7nbpIZKXXnfMXg= -gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= +gocloud.dev v0.27.0 h1:j0WTUsnKTxCsWO7y8T+YCiBZUmLl9w/WIowqAY3yo0g= +gocloud.dev v0.27.0/go.mod h1:YlYKhYsY5/1JdHGWQDkAuqkezVKowu7qbe9aIeUF6p0= +golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= +golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -583,20 +1552,35 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -607,26 +1591,46 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -649,12 +1653,18 @@ golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220628200809-02e64fa58f26/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= +golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -662,32 +1672,65 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -695,50 +1738,91 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -751,32 +1835,53 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= +golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -797,31 +1902,46 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= +golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= +google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= +google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -856,17 +1976,22 @@ google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3l google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= -google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= -google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= -google.golang.org/api v0.68.0/go.mod h1:sOM8pTpwgflXRhz+oC8H2Dr+UcbMqkPPWNJo88Q7TH8= -google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= +google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= +google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= +google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= +google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= +google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.91.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.99.0 h1:tsBtOIklCE2OFxhmcYSVqGwSAN/Y897srxmcvAQnwK8= google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -874,11 +1999,14 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= +google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= +google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -887,6 +2015,7 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -895,17 +2024,21 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -913,6 +2046,7 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= @@ -941,27 +2075,42 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220204002441-d6cc3cc0770e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= -google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= -google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= +google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= +google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= +google.golang.org/genproto v0.0.0-20220802133213-ce4fa296bf78/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b h1:IOQ/4u8ZSLV+xns0LQxzdAcdOJTDMWB+0shVM8KWXBE= google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= +google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= +google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= +google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -984,8 +2133,14 @@ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= +google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= +google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= +google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -1005,21 +2160,52 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= +gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= +gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= +gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/telebot.v3 v3.0.0/go.mod h1:7rExV8/0mDDNu9epSrDm/8j22KLaActH1Tbee6YjzWg= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= +gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= +honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -1027,7 +2213,80 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= +k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= +k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= +k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= +k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= +k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg= +k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= +k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= +k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= +k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= +k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= +k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= +k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= +k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= +k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= +k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= +k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= +k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= +k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= +k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= +k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= +k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30= +k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= +k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= +k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= +k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= +k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= +k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= +k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= +k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= +k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4= +k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= +k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= +k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= +k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= +k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= +k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= +k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/klog/v2 v2.70.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= +k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= +k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= +k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= +k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= +k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= +k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= +k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= +nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= +sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= +sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= +sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= +sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= +sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= +sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= +sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= +sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= From ab1d5b5623a06d393fdf962bd1566b2488fa5a86 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 8 Nov 2022 17:34:21 +1100 Subject: [PATCH 122/172] Bump google.golang.org/api from 0.88.0 to 0.102.0 (#227) Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.88.0 to 0.102.0. - [Release notes](https://github.com/googleapis/google-api-go-client/releases) - [Changelog](https://github.com/googleapis/google-api-go-client/blob/main/CHANGES.md) - [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.88.0...v0.102.0) --- updated-dependencies: - dependency-name: google.golang.org/api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- go.mod | 7 ++++--- go.sum | 14 ++++++++------ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/go.mod b/go.mod index d776de8c..185c46ba 100644 --- a/go.mod +++ b/go.mod @@ -13,13 +13,14 @@ require ( github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 go.uber.org/zap v1.23.0 gocloud.dev v0.27.0 - google.golang.org/api v0.99.0 + google.golang.org/api v0.102.0 gopkg.in/yaml.v3 v3.0.1 ) require ( cloud.google.com/go v0.104.0 // indirect - cloud.google.com/go/compute v1.10.0 // indirect + cloud.google.com/go/compute v1.12.1 // indirect + cloud.google.com/go/compute/metadata v0.2.1 // indirect cloud.google.com/go/iam v0.5.0 // indirect cloud.google.com/go/pubsub v1.26.0 // indirect cloud.google.com/go/storage v1.27.0 // indirect @@ -72,7 +73,7 @@ require ( golang.org/x/text v0.4.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b // indirect + google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect google.golang.org/grpc v1.50.1 // indirect google.golang.org/protobuf v1.28.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 22d583de..c061aceb 100644 --- a/go.sum +++ b/go.sum @@ -50,8 +50,10 @@ cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6m cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= -cloud.google.com/go/compute v1.10.0 h1:aoLIYaA1fX3ywihqpBk2APQKOo20nXsp1GEZQbx5Jk4= -cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= +cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= +cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= +cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= +cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxBkeanZ9wwa75XHJgOM= cloud.google.com/go/datacatalog v1.6.0 h1:xzXGAE2fAuMh+ksODKr9nRv9ega1vHjFwRqMA8tRrVE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= @@ -1988,8 +1990,8 @@ google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6F google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.91.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.99.0 h1:tsBtOIklCE2OFxhmcYSVqGwSAN/Y897srxmcvAQnwK8= -google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= +google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I= +google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -2098,8 +2100,8 @@ google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljW google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= google.golang.org/genproto v0.0.0-20220802133213-ce4fa296bf78/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b h1:IOQ/4u8ZSLV+xns0LQxzdAcdOJTDMWB+0shVM8KWXBE= -google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= +google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= From 86400a1764d0ba959554d20e5b162f24fc5959ae Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 9 Nov 2022 13:50:28 +1100 Subject: [PATCH 123/172] Add a marker file type to specify how the outfile is written to the marker. (#233) Refactors the marker file support to introduce a type that changes how the output path is stored in the marker file. Type supports the scorecard controller better as it expects a dir without the bucket prefix. Additional changes: * Fix a bug with how cloudstorage handles local files. * Add marker type to k8s and docker-compose configs. * Fix linter warnings * Make marker.Type.transform private. Signed-off-by: Caleb Brown --- cmd/enumerate_github/main.go | 27 +-- cmd/enumerate_github/marker/type.go | 89 +++++++++ cmd/enumerate_github/marker/type_test.go | 214 +++++++++++++++++++++ cmd/enumerate_github/marker/write.go | 42 ++++ cmd/enumerate_github/marker/write_test.go | 44 +++++ go.work.sum | 11 +- infra/k8s/enumerate_github.yaml | 2 + infra/test/docker-compose.yml | 1 + internal/cloudstorage/cloudstorage.go | 15 +- internal/cloudstorage/cloudstorage_test.go | 22 ++- 10 files changed, 428 insertions(+), 39 deletions(-) create mode 100644 cmd/enumerate_github/marker/type.go create mode 100644 cmd/enumerate_github/marker/type_test.go create mode 100644 cmd/enumerate_github/marker/write.go create mode 100644 cmd/enumerate_github/marker/write_test.go diff --git a/cmd/enumerate_github/main.go b/cmd/enumerate_github/main.go index 355f241d..d215feb6 100644 --- a/cmd/enumerate_github/main.go +++ b/cmd/enumerate_github/main.go @@ -33,8 +33,8 @@ import ( "go.uber.org/zap/zapcore" "github.com/ossf/criticality_score/cmd/enumerate_github/githubsearch" + "github.com/ossf/criticality_score/cmd/enumerate_github/marker" "github.com/ossf/criticality_score/cmd/enumerate_github/repowriter" - "github.com/ossf/criticality_score/internal/cloudstorage" "github.com/ossf/criticality_score/internal/envflag" log "github.com/ossf/criticality_score/internal/log" "github.com/ossf/criticality_score/internal/outfile" @@ -66,6 +66,7 @@ var ( logLevel = defaultLogLevel logEnv log.Env format repowriter.WriterType + markerType marker.Type // Maps environment variables to the flags they correspond to. envFlagMap = envflag.Map{ @@ -78,6 +79,7 @@ var ( "CRITICALITY_SCORE_OUTFILE": "out", "CRITICALITY_SCORE_OUTFILE_FORCE": "force", "CRITICALITY_SCORE_MARKER": "marker", + "CRITICALITY_SCORE_MARKER_TYPE": "marker-type", "CRITICALITY_SCORE_QUERY": "query", "CRITICALITY_SCORE_STARS_MIN": "min-stars", "CRITICALITY_SCORE_STARS_OVERLAP": "star-overlap", @@ -112,6 +114,7 @@ func init() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&format, "format", repowriter.WriterTypeText, "set output file `format`.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") + flag.TextVar(&markerType, "marker-type", marker.TypeFull, "format of the contents in the marker file. Can be 'full', 'dir' or 'file'.") outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "FILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -154,26 +157,6 @@ func searchWorker(s *githubsearch.Searcher, logger *zap.Logger, queries, results } } -func writeMarker(ctx context.Context, markerFile, outFile string) (err error) { - marker, e := cloudstorage.NewWriter(ctx, markerFile) - if e != nil { - return fmt.Errorf("open marker: %w", e) - } - defer func() { - if e := marker.Close(); e != nil { - // Return the error using the named return value if it isn't - // already set. - if e == nil { - err = fmt.Errorf("closing marker: %w", e) - } - } - }() - if _, e := fmt.Fprintln(marker, outFile); e != nil { - err = fmt.Errorf("writing marker: %w", e) - } - return -} - func main() { envflag.Parse(envFlagMap) @@ -294,7 +277,7 @@ func main() { logger = logger.With(zap.String("marker_filename", *markerFileFlag)) logger.Debug("Writing the marker file") - if err := writeMarker(ctx, *markerFileFlag, out.Name()); err != nil { + if err := marker.Write(ctx, markerType, *markerFileFlag, out.Name()); err != nil { logger.Error("Failed creating marker file", zap.Error(err)) // Don't exit after a failure to create the marker file. Just fail // to write the marker file. diff --git a/cmd/enumerate_github/marker/type.go b/cmd/enumerate_github/marker/type.go new file mode 100644 index 00000000..4534e40d --- /dev/null +++ b/cmd/enumerate_github/marker/type.go @@ -0,0 +1,89 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package marker + +import ( + "bytes" + "errors" + "net/url" + "path" + "strings" +) + +type Type int + +const ( + TypeFull = Type(iota) + TypeFile + TypeDir +) + +var ErrorUnknownType = errors.New("unknown marker type") + +// String implements the fmt.Stringer interface. +func (t Type) String() string { + text, err := t.MarshalText() + if err != nil { + return "" + } + return string(text) +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (t Type) MarshalText() ([]byte, error) { + switch t { + case TypeFull: + return []byte("full"), nil + case TypeFile: + return []byte("file"), nil + case TypeDir: + return []byte("dir"), nil + default: + return []byte{}, ErrorUnknownType + } +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (t *Type) UnmarshalText(text []byte) error { + switch { + case bytes.Equal(text, []byte("full")): + *t = TypeFull + case bytes.Equal(text, []byte("file")): + *t = TypeFile + case bytes.Equal(text, []byte("dir")): + *t = TypeDir + default: + return ErrorUnknownType + } + return nil +} + +func (t Type) transform(p string) string { + if t == TypeFull { + return p + } + // Is this a bucket URL? + if u, err := url.Parse(p); err == nil && u.IsAbs() { + if u.Scheme == "file" && u.Host == "" { + p = u.Path + } else { + p = strings.TrimPrefix(u.Path, "/") + } + } + if t == TypeDir { + return path.Dir(p) + } + return p +} diff --git a/cmd/enumerate_github/marker/type_test.go b/cmd/enumerate_github/marker/type_test.go new file mode 100644 index 00000000..26e1fd3e --- /dev/null +++ b/cmd/enumerate_github/marker/type_test.go @@ -0,0 +1,214 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package marker_test + +import ( + "context" + "os" + "path" + "strings" + "testing" + + "github.com/ossf/criticality_score/cmd/enumerate_github/marker" +) + +func TestTransform(t *testing.T) { + tests := []struct { + name string + in string + want string + t marker.Type + }{ + { + name: "full-bucket-gs", + t: marker.TypeFull, + in: "gs://bucket/path/to/file.txt?arg", + want: "gs://bucket/path/to/file.txt?arg", + }, + { + name: "file-bucket-gs", + t: marker.TypeFile, + in: "gs://bucket/path/to/file.txt?arg", + want: "path/to/file.txt", + }, + { + name: "dir-bucket-gs", + t: marker.TypeDir, + in: "gs://bucket/path/to/file.txt?arg", + want: "path/to", + }, + { + name: "file-bucket-file-abs", + t: marker.TypeFile, + in: "file:///path/to/file.txt?arg", + want: "/path/to/file.txt", + }, + { + name: "file-bucket-file-rel", + t: marker.TypeFile, + in: "file://./path/to/file.txt?arg", + want: "path/to/file.txt", + }, + { + name: "full-path-abs", + t: marker.TypeFull, + in: "/path/to/file.txt", + want: "/path/to/file.txt", + }, + { + name: "file-path-abs", + t: marker.TypeFile, + in: "/path/to/file.txt", + want: "/path/to/file.txt", + }, + { + name: "dir-path-abs", + t: marker.TypeDir, + in: "/path/to/file.txt", + want: "/path/to", + }, + { + name: "full-path-rel", + t: marker.TypeFull, + in: "../path/to/file.txt", + want: "../path/to/file.txt", + }, + { + name: "file-path-rel", + t: marker.TypeFile, + in: "../path/to/file.txt", + want: "../path/to/file.txt", + }, + { + name: "dir-path-rel", + t: marker.TypeDir, + in: "../path/to/file.txt", + want: "../path/to", + }, + { + name: "full-invalid-url", + t: marker.TypeFull, + in: "::/path/to/file.txt", + want: "::/path/to/file.txt", + }, + { + name: "file-invalid-url", + t: marker.TypeFile, + in: "::/path/to/file.txt", + want: "::/path/to/file.txt", + }, + { + name: "dir-invalid-url", + t: marker.TypeDir, + in: "::/path/to/file.txt", + want: "::/path/to", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + markerFile := path.Join(t.TempDir(), "marker.out") + err := marker.Write(context.Background(), test.t, markerFile, test.in) + if err != nil { + t.Fatalf("Write() = %v, want no error", err) + } + markerContents, err := os.ReadFile(markerFile) + if err != nil { + t.Fatalf("ReadFile() = %v, want no error", err) + } + if got := strings.TrimSpace(string(markerContents)); got != test.want { + t.Fatalf("marker content = %q, want %q", got, test.want) + } + }) + } +} + +func TestUnmarshal(t *testing.T) { + tests := []struct { + in string + want marker.Type + wantErr bool + }{ + { + in: "full", + want: marker.TypeFull, + }, + { + in: "file", + want: marker.TypeFile, + }, + { + in: "dir", + want: marker.TypeDir, + }, + { + in: "notamarker", + wantErr: true, + }, + } + for _, test := range tests { + t.Run(test.in, func(t *testing.T) { + var got marker.Type + err := got.UnmarshalText([]byte(test.in)) + if test.wantErr && err == nil { + t.Fatal("UnmarshalText() = nil, want an error") + } + if !test.wantErr && err != nil { + t.Fatalf("UnmarshalText() = %v, want no error", err) + } + if test.want != got { + t.Fatalf("UnmarshalText() parsed %s, want %s", got, test.want) + } + }) + } +} + +func TestMarshal(t *testing.T) { + tests := []struct { + want string + in marker.Type + wantErr bool + }{ + { + in: marker.TypeFull, + want: "full", + }, + { + in: marker.TypeFile, + want: "file", + }, + { + in: marker.TypeDir, + want: "dir", + }, + { + in: marker.Type(99999), + wantErr: true, + }, + } + for _, test := range tests { + t.Run(test.in.String(), func(t *testing.T) { + got, err := test.in.MarshalText() + if test.wantErr && err == nil { + t.Fatal("UnmarshalText() = nil, want an error") + } + if !test.wantErr && err != nil { + t.Fatalf("UnmarshalText() = %v, want no error", err) + } + if test.want != string(got) { + t.Fatalf("UnmarshalText() parsed %s, want %s", got, test.want) + } + }) + } +} diff --git a/cmd/enumerate_github/marker/write.go b/cmd/enumerate_github/marker/write.go new file mode 100644 index 00000000..22a189e4 --- /dev/null +++ b/cmd/enumerate_github/marker/write.go @@ -0,0 +1,42 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package marker + +import ( + "context" + "fmt" + + "github.com/ossf/criticality_score/internal/cloudstorage" +) + +func Write(ctx context.Context, t Type, markerFile, outFile string) (err error) { + marker, e := cloudstorage.NewWriter(ctx, markerFile) + if e != nil { + return fmt.Errorf("open marker: %w", e) + } + defer func() { + if e := marker.Close(); e != nil { + // Return the error using the named return value if it isn't + // already set. + if e == nil { + err = fmt.Errorf("closing marker: %w", e) + } + } + }() + if _, e := fmt.Fprintln(marker, t.transform(outFile)); e != nil { + err = fmt.Errorf("writing marker: %w", e) + } + return +} diff --git a/cmd/enumerate_github/marker/write_test.go b/cmd/enumerate_github/marker/write_test.go new file mode 100644 index 00000000..9d0c5006 --- /dev/null +++ b/cmd/enumerate_github/marker/write_test.go @@ -0,0 +1,44 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package marker_test + +import ( + "context" + "os" + "path" + "strings" + "testing" + + "github.com/ossf/criticality_score/cmd/enumerate_github/marker" +) + +func TestWrite(t *testing.T) { + want := "this/is/a/path" + dir := t.TempDir() + file := path.Join(dir, "marker.test") + + err := marker.Write(context.Background(), marker.TypeFull, file, want) + if err != nil { + t.Fatalf("Write() = %v, want no error", err) + } + + markerContents, err := os.ReadFile(file) + if err != nil { + t.Fatalf("ReadFile() = %v, want no error", err) + } + if got := strings.TrimSpace(string(markerContents)); got != want { + t.Fatalf("marker contents = %q, want %q", got, want) + } +} diff --git a/go.work.sum b/go.work.sum index 4716b5fb..a4069aab 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,3 +1,4 @@ +cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= cloud.google.com/go/monitoring v1.4.0 h1:05+IuNMbh40hbxcqQ4SnynbwZbLG1Wc9dysIJxnfv7U= cloud.google.com/go/pubsub v1.20.0 h1:QuwfH5BpEIE9T3n0YK3PKlsXi/TmHMu593UpOVlWygI= cloud.google.com/go/trace v1.2.0 h1:oIaB4KahkIUOpLSAAjEJ8y2desbjY/x/RfP4O3KAtTI= @@ -6,15 +7,16 @@ contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaL github.com/caarlos0/env/v6 v6.9.1 h1:zOkkjM0F6ltnQ5eBX6IPI41UP/KDGEK7rRPwGCNos8k= github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jszwec/csvutil v1.6.0 h1:QORXquCT0t8nUKD7utAD4HDmQMgG0Ir9WieZXzpa7ms= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/moby/buildkit v0.8.3 h1:vFlwUQ6BZE1loZ8zoZH3fYgmA1djFCS3DrOhCVU6ZZE= +github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= +github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= github.com/rhysd/actionlint v1.6.11 h1:8aD7ozc43RbnKwUmFvRtfW0LTW6f13MTXFDlf+0PNAc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= @@ -27,13 +29,16 @@ github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHo github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= +google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= mvdan.cc/sh/v3 v3.4.3 h1:zbuKH7YH9cqU6PGajhFFXZY7dhPXcDr55iN/cUAqpuw= diff --git a/infra/k8s/enumerate_github.yaml b/infra/k8s/enumerate_github.yaml index 1c28cd65..5d3ca6a9 100644 --- a/infra/k8s/enumerate_github.yaml +++ b/infra/k8s/enumerate_github.yaml @@ -39,6 +39,8 @@ spec: value: "1" - name: CRITICALITY_SCORE_MARKER value: "gs://ossf-criticality-score-url-data/latest" + - name: CRITICALITY_SCORE_MARKER_TYPE + value: "dir" - name: CRITICALITY_SCORE_STARS_MIN value: "20" - name: CRITICALITY_SCORE_START_DATE diff --git a/infra/test/docker-compose.yml b/infra/test/docker-compose.yml index 9369efec..68f6dd0e 100644 --- a/infra/test/docker-compose.yml +++ b/infra/test/docker-compose.yml @@ -49,6 +49,7 @@ services: CRITICALITY_SCORE_START_DATE: ${CRITICALITY_SCORE_START_DATE} CRITICALITY_SCORE_END_DATE: ${CRITICALITY_SCORE_END_DATE} CRITICALITY_SCORE_MARKER: s3://criticality_score/enumeration/latest.txt?endpoint=minio:9000&disableSSL=true&s3ForcePathStyle=true + CRITICALITY_SCORE_MARKER_TYPE: dir GITHUB_AUTH_SERVER: auth:8080 AWS_ACCESS_KEY_ID: minio AWS_SECRET_ACCESS_KEY: minio123 diff --git a/internal/cloudstorage/cloudstorage.go b/internal/cloudstorage/cloudstorage.go index 6f635c23..b58f302b 100644 --- a/internal/cloudstorage/cloudstorage.go +++ b/internal/cloudstorage/cloudstorage.go @@ -29,6 +29,8 @@ import ( _ "gocloud.dev/blob/s3blob" ) +const fileScheme = "file" + func parseBucketAndPrefix(rawURL string) (bucket, prefix string, _ error) { u, err := url.Parse(rawURL) if err != nil { @@ -46,7 +48,7 @@ func parseBucketAndPrefix(rawURL string) (bucket, prefix string, _ error) { } // Assume a scheme-less, host-less url is a local file. - u.Scheme = "file" + u.Scheme = fileScheme if !path.IsAbs(u.Path) { u.Host = "." } @@ -56,9 +58,14 @@ func parseBucketAndPrefix(rawURL string) (bucket, prefix string, _ error) { u.RawQuery = q.Encode() } - // gocloud.dev expects prefix/key and bucket to be separate values. - prefix = strings.TrimPrefix(u.Path, "/") - u.Path = "" + if u.Scheme == fileScheme { + // File schemes are treated differently, as the dir forms the bucket. + u.Path, prefix = path.Split(u.Path) + } else { + prefix = strings.TrimPrefix(u.Path, "/") + u.Path = "" + } + bucket = u.String() return bucket, prefix, nil } diff --git a/internal/cloudstorage/cloudstorage_test.go b/internal/cloudstorage/cloudstorage_test.go index 16d6298b..3472c6e8 100644 --- a/internal/cloudstorage/cloudstorage_test.go +++ b/internal/cloudstorage/cloudstorage_test.go @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -//nolint:goconst package cloudstorage import ( @@ -26,9 +25,9 @@ func TestParseBucketAndPrefixAbsLocalFile(t *testing.T) { if err != nil { t.Fatalf("parseBucketAndPrefix() = %v, want no error", err) } - assertBucket(t, b, "file", "", map[string]string{"metadata": "skip"}) - if p != "path/to/file" { - t.Fatalf("Prefix = %v; want path/to/file", p) + assertBucket(t, b, fileScheme, "", "/path/to/", map[string]string{"metadata": "skip"}) + if p != "file" { + t.Fatalf("Prefix = %v; want file", p) } } @@ -37,9 +36,9 @@ func TestParseBucketAndPrefixRelativeLocalFile(t *testing.T) { if err != nil { t.Fatalf("parseBucketAndPrefix() = %v, want no error", err) } - assertBucket(t, b, "file", ".", map[string]string{"metadata": "skip"}) - if p != "path/to/file" { - t.Fatalf("Prefix = %v; want path/to/file", p) + assertBucket(t, b, fileScheme, ".", "/path/to/", map[string]string{"metadata": "skip"}) + if p != "file" { + t.Fatalf("Prefix = %v; want file", p) } } @@ -48,7 +47,7 @@ func TestParseBucketAndPrefixS3URL(t *testing.T) { if err != nil { t.Fatalf("parseBucketAndPrefix() = %v, want no error", err) } - assertBucket(t, b, "s3", "bucket", map[string]string{}) + assertBucket(t, b, "s3", "bucket", "", map[string]string{}) if p != "path/to/file" { t.Fatalf("Prefix = %v; want path/to/file", p) } @@ -85,7 +84,7 @@ func TestNewWriter(t *testing.T) { } } -func assertBucket(t *testing.T, bucket, wantScheme, wantHost string, wantQuery map[string]string) { +func assertBucket(t *testing.T, bucket, wantScheme, wantHost, wantPath string, wantQuery map[string]string) { t.Helper() u, err := url.Parse(bucket) if err != nil { @@ -95,7 +94,10 @@ func assertBucket(t *testing.T, bucket, wantScheme, wantHost string, wantQuery m t.Fatalf("Bucket scheme = %q, want %q", u.Scheme, wantScheme) } if u.Host != wantHost { - t.Fatalf("Bucket host = %q, want %q", u.Scheme, wantHost) + t.Fatalf("Bucket host = %q, want %q", u.Host, wantHost) + } + if u.Path != wantPath { + t.Fatalf("Bucket path = %q, want %q", u.Path, wantPath) } for k, want := range wantQuery { if !u.Query().Has(k) { From eadd32deca146542a99e7de38e206a801889fc9f Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 9 Nov 2022 16:23:42 +1100 Subject: [PATCH 124/172] Add a cloudbuild.yaml for collect_signals worker. (#234) Signed-off-by: Caleb Brown --- .../collect_signals/cloudbuild.yaml | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 infra/cloudbuild/collect_signals/cloudbuild.yaml diff --git a/infra/cloudbuild/collect_signals/cloudbuild.yaml b/infra/cloudbuild/collect_signals/cloudbuild.yaml new file mode 100644 index 00000000..006d273a --- /dev/null +++ b/infra/cloudbuild/collect_signals/cloudbuild.yaml @@ -0,0 +1,22 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +steps: +- name: 'gcr.io/cloud-builders/docker' + args: ['build', '.', + '--build-arg', 'COMMIT_SHA=$COMMIT_SHA', + '-t', 'gcr.io/openssf/criticality-score-collect-signals:$COMMIT_SHA', + '-t', 'gcr.io/openssf/criticality-score-collect-signals:latest', + '-f', 'cmd/collect_signals/Dockerfile'] +images: ['gcr.io/openssf/criticality-score-collect-signals'] From 41d32277b73210f63d3c7de28f7cd396fbaac6ea Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 9 Nov 2022 17:23:28 +1100 Subject: [PATCH 125/172] Make collect_signals Dockerfile work without buildkit (#235) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- cmd/collect_signals/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/collect_signals/Dockerfile b/cmd/collect_signals/Dockerfile index b2326af5..16beec71 100644 --- a/cmd/collect_signals/Dockerfile +++ b/cmd/collect_signals/Dockerfile @@ -23,8 +23,9 @@ FROM base AS collect_signals ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 go build ./cmd/collect_signals +RUN chmod -R 0775 /src/config/scorer/* FROM gcr.io/distroless/base:nonroot@sha256:533c15ef2acb1d3b1cd4e58d8aa2740900cae8f579243a53c53a6e28bcac0684 COPY --from=collect_signals /src/collect_signals ./collect_signals -COPY --from=collect_signals --chmod=775 /src/config/scorer/* ./config/scorer/ +COPY --from=collect_signals /src/config/scorer/* ./config/scorer/ ENTRYPOINT ["./collect_signals"] From 04414756670939d42b2c3abc1e43d7f827723153 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 11 Nov 2022 15:35:32 +1100 Subject: [PATCH 126/172] Include the job time in the output data for BQ partitioning. (#236) Signed-off-by: Caleb Brown --- cmd/collect_signals/worker.go | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/cmd/collect_signals/worker.go b/cmd/collect_signals/worker.go index 5041375e..8c408672 100644 --- a/cmd/collect_signals/worker.go +++ b/cmd/collect_signals/worker.go @@ -17,6 +17,8 @@ import ( "github.com/ossf/criticality_score/internal/signalio" ) +const collectionDateColumnName = "collection_date" + type collectWorker struct { logger *zap.Logger c *collector.Collector @@ -27,11 +29,12 @@ type collectWorker struct { // Process implements the worker.Worker interface. func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchRequest, bucketURL string) error { filename := worker.ResultFilename(req) + jobTime := req.GetJobTime().AsTime() // Prepare the logger with identifiers for the shard and job. logger := w.logger.With( zap.Int32("shard_id", req.GetShardNum()), - zap.Time("job_time", req.GetJobTime().AsTime()), + zap.Time("job_time", jobTime), zap.String("filename", filename), ) logger.Info("Processing shard") @@ -41,6 +44,7 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq if w.s != nil { extras = append(extras, w.scoreColumnName) } + extras = append(extras, collectionDateColumnName) var output bytes.Buffer out := signalio.CsvWriter(&output, w.c.EmptySets(), extras...) @@ -82,6 +86,12 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq extras = append(extras, f) } + // Ensure the collection date is included with each record for paritioning. + extras = append(extras, signalio.Field{ + Key: collectionDateColumnName, + Value: jobTime, + }) + // Write the signals to storage. if err := out.WriteSignals(ss, extras...); err != nil { return fmt.Errorf("failed writing signals: %w", err) From abec132c8984c88cf153d04f4d01654088e63e8e Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 11 Nov 2022 15:51:53 +1100 Subject: [PATCH 127/172] Add JSON support for outputting signals. (#237) The Scorecard transfer expects to see JSON to import. I was planning to add this anyway, but the BQ load just expidited this. Signed-off-by: Caleb Brown --- cmd/collect_signals/main.go | 11 ++- cmd/collect_signals/worker.go | 6 +- cmd/criticality_score/main.go | 4 +- internal/collector/signal/signal.go | 26 ++++++- internal/signalio/csv.go | 2 +- internal/signalio/json.go | 69 ++++++++++++++++++ internal/signalio/type.go | 79 +++++++++++++++++++++ internal/signalio/type_test.go | 104 ++++++++++++++++++++++++++++ 8 files changed, 294 insertions(+), 7 deletions(-) create mode 100644 internal/signalio/json.go create mode 100644 internal/signalio/type.go create mode 100644 internal/signalio/type_test.go diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index b16e42d2..8fbfdb46 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -27,6 +27,7 @@ import ( "github.com/ossf/criticality_score/internal/collector" log "github.com/ossf/criticality_score/internal/log" + "github.com/ossf/criticality_score/internal/signalio" ) const defaultLogLevel = zapcore.InfoLevel @@ -67,6 +68,14 @@ func main() { } defer logger.Sync() + // Parse the output format. + formatType := signalio.WriterTypeCSV + if val := criticalityConfig["output-format"]; val != "" { + if err := formatType.UnmarshalText([]byte(val)); err != nil { + panic(err) + } + } + // Extract the GCP project ID. gcpProjectID, err := config.GetProjectID() if err != nil { @@ -109,7 +118,7 @@ func main() { collector.GCPDatasetName(gcpDatasetName), } - w, err := NewWorker(context.Background(), logger, scoringEnabled, scoringConfigFile, scoringColumnName, opts) + w, err := NewWorker(context.Background(), logger, formatType, scoringEnabled, scoringConfigFile, scoringColumnName, opts) if err != nil { // Fatal exits. logger.With(zap.Error(err)).Fatal("Failed to create worker") diff --git a/cmd/collect_signals/worker.go b/cmd/collect_signals/worker.go index 8c408672..b4a16bdf 100644 --- a/cmd/collect_signals/worker.go +++ b/cmd/collect_signals/worker.go @@ -24,6 +24,7 @@ type collectWorker struct { c *collector.Collector s *scorer.Scorer scoreColumnName string + writerType signalio.WriterType } // Process implements the worker.Worker interface. @@ -46,7 +47,7 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq } extras = append(extras, collectionDateColumnName) var output bytes.Buffer - out := signalio.CsvWriter(&output, w.c.EmptySets(), extras...) + out := w.writerType.New(&output, w.c.EmptySets(), extras...) // Iterate through the repos in this shard. for _, repo := range req.GetRepos() { @@ -135,7 +136,7 @@ func getScorer(logger *zap.Logger, scoringEnabled bool, scoringConfigFile string return s, nil } -func NewWorker(ctx context.Context, logger *zap.Logger, scoringEnabled bool, scoringConfigFile, scoringColumn string, collectOpts []collector.Option) (*collectWorker, error) { +func NewWorker(ctx context.Context, logger *zap.Logger, writerType signalio.WriterType, scoringEnabled bool, scoringConfigFile, scoringColumn string, collectOpts []collector.Option) (*collectWorker, error) { logger.Info("Initializing worker") c, err := collector.New(ctx, logger, collectOpts...) @@ -159,6 +160,7 @@ func NewWorker(ctx context.Context, logger *zap.Logger, scoringEnabled bool, sco c: c, s: s, scoreColumnName: scoringColumn, + writerType: writerType, }, nil } diff --git a/cmd/criticality_score/main.go b/cmd/criticality_score/main.go index 07b8112b..0a98dcc2 100644 --- a/cmd/criticality_score/main.go +++ b/cmd/criticality_score/main.go @@ -48,12 +48,14 @@ var ( workersFlag = flag.Int("workers", 1, "the total number of concurrent workers to use.") logLevel = defaultLogLevel logEnv log.Env + formatType signalio.WriterType ) // initFlags prepares any runtime flags, usage information and parses the flags. func initFlags() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") + flag.TextVar(&formatType, "format", signalio.WriterTypeCSV, "set the output format.") outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "OUTFILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) @@ -181,7 +183,7 @@ func main() { if s != nil { extras = append(extras, scoreColumnName) } - out := signalio.CsvWriter(w, c.EmptySets(), extras...) + out := formatType.New(w, c.EmptySets(), extras...) // Start the workers that process a channel of repo urls. repos := make(chan *url.URL) diff --git a/internal/collector/signal/signal.go b/internal/collector/signal/signal.go index 651916cc..d2cb14c1 100644 --- a/internal/collector/signal/signal.go +++ b/internal/collector/signal/signal.go @@ -36,7 +36,7 @@ const ( // namespaceLegacy is an internal namespace used for fields that provide // compatibility with the legacy python implementation. - namespaceLegacy Namespace = "legacy" + NamespaceLegacy Namespace = "legacy" // The following constants are used while parsing the tags for the struct // fields in a Set. @@ -213,7 +213,7 @@ func SetFields(s Set, namespace bool) []string { legacyPrefix := "" if namespace { prefix = fmt.Sprintf("%s%c", s.Namespace(), nameSeparator) - legacyPrefix = fmt.Sprintf("%s%c", namespaceLegacy, nameSeparator) + legacyPrefix = fmt.Sprintf("%s%c", NamespaceLegacy, nameSeparator) } _ = iterSetFields(s, func(f *fieldConfig, _ any) error { if f.legacy { @@ -253,3 +253,25 @@ func SetAsMap(s Set, namespace bool) map[string]any { } return m } + +// SetAsMapWithNamespace returns a map where the outer map contains keys +// corresponding to the namespace, and each inner map contains each field name +// mapped to the value of the field. +func SetAsMapWithNamespace(s Set) map[string]map[string]any { + m := make(map[string]map[string]any) + _ = iterSetFields(s, func(f *fieldConfig, v any) error { + // Determine which namespace to use. + ns := s.Namespace().String() + if f.legacy { + ns = NamespaceLegacy.String() + } + innerM, ok := m[ns] + if !ok { + innerM = make(map[string]any) + m[ns] = innerM + } + innerM[f.name] = v + return nil + }) + return m +} diff --git a/internal/signalio/csv.go b/internal/signalio/csv.go index cf1965ab..efa96bb7 100644 --- a/internal/signalio/csv.go +++ b/internal/signalio/csv.go @@ -46,7 +46,7 @@ func headerFromSignalSets(sets []signal.Set, extra []string) []string { return hs } -func CsvWriter(w io.Writer, emptySets []signal.Set, extra ...string) Writer { +func CSVWriter(w io.Writer, emptySets []signal.Set, extra ...string) Writer { return &csvWriter{ header: headerFromSignalSets(emptySets, extra), w: csv.NewWriter(w), diff --git a/internal/signalio/json.go b/internal/signalio/json.go new file mode 100644 index 00000000..bea884e2 --- /dev/null +++ b/internal/signalio/json.go @@ -0,0 +1,69 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package signalio + +import ( + "encoding/json" + "fmt" + "io" + "sync" + + "github.com/ossf/criticality_score/internal/collector/signal" +) + +type jsonWriter struct { + encoder *json.Encoder + + // Prevents concurrent writes to w. + mu sync.Mutex +} + +func JSONWriter(w io.Writer) Writer { + e := json.NewEncoder(w) + e.SetIndent("", "") + return &jsonWriter{ + encoder: e, + } +} + +// WriteSignals implements the Writer interface. +func (w *jsonWriter) WriteSignals(signals []signal.Set, extra ...Field) error { + data := make(map[string]any) + for _, s := range signals { + m := signal.SetAsMapWithNamespace(s) + + // Merge m with data + for ns, innerM := range m { + d, ok := data[ns] + if !ok { + d = make(map[string]any) + data[ns] = d + } + nsData, ok := d.(map[string]any) + if !ok { + return fmt.Errorf("failed to get map for namespace: %s", ns) + } + for k, v := range innerM { + nsData[k] = v + } + } + } + for _, f := range extra { + data[f.Key] = f.Value + } + w.mu.Lock() + defer w.mu.Unlock() + return w.encoder.Encode(data) +} diff --git a/internal/signalio/type.go b/internal/signalio/type.go new file mode 100644 index 00000000..03ee77ee --- /dev/null +++ b/internal/signalio/type.go @@ -0,0 +1,79 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package signalio + +import ( + "bytes" + "errors" + "io" + + "github.com/ossf/criticality_score/internal/collector/signal" +) + +type WriterType int + +const ( + WriterTypeCSV = WriterType(iota) + WriterTypeJSON +) + +var ErrorUnknownWriterType = errors.New("unknown writer type") + +// String implements the fmt.Stringer interface. +func (t WriterType) String() string { + text, err := t.MarshalText() + if err != nil { + return "" + } + return string(text) +} + +// MarshalText implements the encoding.TextMarshaler interface. +func (t WriterType) MarshalText() ([]byte, error) { + switch t { + case WriterTypeCSV: + return []byte("csv"), nil + case WriterTypeJSON: + return []byte("json"), nil + default: + return []byte{}, ErrorUnknownWriterType + } +} + +// UnmarshalText implements the encoding.TextUnmarshaler interface. +func (t *WriterType) UnmarshalText(text []byte) error { + switch { + case bytes.Equal(text, []byte("csv")): + *t = WriterTypeCSV + case bytes.Equal(text, []byte("json")): + *t = WriterTypeJSON + default: + return ErrorUnknownWriterType + } + return nil +} + +// New will return a new instance of the corresponding implementation of +// Writer for the given WriterType. +func (t *WriterType) New(w io.Writer, emptySets []signal.Set, extra ...string) Writer { + switch *t { + case WriterTypeCSV: + return CSVWriter(w, emptySets, extra...) + case WriterTypeJSON: + return JSONWriter(w) + default: + return nil + } +} diff --git a/internal/signalio/type_test.go b/internal/signalio/type_test.go new file mode 100644 index 00000000..8497ee4a --- /dev/null +++ b/internal/signalio/type_test.go @@ -0,0 +1,104 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package signalio_test + +import ( + "errors" + "testing" + + "github.com/ossf/criticality_score/internal/signalio" +) + +func TestTypeString(t *testing.T) { + //nolint:govet + tests := []struct { + name string + writerType signalio.WriterType + want string + }{ + {name: "csv", writerType: signalio.WriterTypeCSV, want: "csv"}, + {name: "json", writerType: signalio.WriterTypeJSON, want: "json"}, + {name: "unknown", writerType: signalio.WriterType(10), want: ""}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := test.writerType.String() + if got != test.want { + t.Fatalf("String() == %s, want %s", got, test.want) + } + }) + } +} + +func TestTypeMarshalText(t *testing.T) { + //nolint:govet + tests := []struct { + name string + writerType signalio.WriterType + want string + err error + }{ + {name: "csv", writerType: signalio.WriterTypeCSV, want: "csv"}, + {name: "json", writerType: signalio.WriterTypeJSON, want: "json"}, + {name: "unknown", writerType: signalio.WriterType(10), want: "", err: signalio.ErrorUnknownWriterType}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.writerType.MarshalText() + if err != nil && !errors.Is(err, test.err) { + t.Fatalf("MarhsalText() == %v, want %v", err, test.err) + } + if err == nil { + if test.err != nil { + t.Fatalf("MarshalText() return nil error, want %v", test.err) + } + if string(got) != test.want { + t.Fatalf("MarhsalText() == %s, want %s", got, test.want) + } + } + }) + } +} + +func TestTypeUnmarshalText(t *testing.T) { + //nolint:govet + tests := []struct { + input string + want signalio.WriterType + err error + }{ + {input: "csv", want: signalio.WriterTypeCSV}, + {input: "json", want: signalio.WriterTypeJSON}, + {input: "", want: 0, err: signalio.ErrorUnknownWriterType}, + {input: "unknown", want: 0, err: signalio.ErrorUnknownWriterType}, + } + for _, test := range tests { + t.Run(test.input, func(t *testing.T) { + var got signalio.WriterType + err := got.UnmarshalText([]byte(test.input)) + if err != nil && !errors.Is(err, test.err) { + t.Fatalf("UnmarshalText() == %v, want %v", err, test.err) + } + if err == nil { + if test.err != nil { + t.Fatalf("MarshalText() return nil error, want %v", test.err) + } + if got != test.want { + t.Fatalf("UnmarshalText() parsed %d, want %d", int(got), int(test.want)) + } + } + }) + } +} From 3f65182c02a6321e608a38b535cfa26f7c94261e Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Tue, 15 Nov 2022 10:36:05 +1100 Subject: [PATCH 128/172] Enable metric collection for the worker. (#239) Signed-off-by: Caleb Brown --- cmd/collect_signals/main.go | 1 + cmd/collect_signals/worker.go | 43 +- go.mod | 16 +- go.sum | 1431 +++------------------------------ go.work.sum | 85 +- 5 files changed, 232 insertions(+), 1344 deletions(-) diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 8fbfdb46..3f6b8029 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -123,6 +123,7 @@ func main() { // Fatal exits. logger.With(zap.Error(err)).Fatal("Failed to create worker") } + defer w.Close() loop := worker.NewWorkLoop(w) if err := loop.Run(); err != nil { diff --git a/cmd/collect_signals/worker.go b/cmd/collect_signals/worker.go index b4a16bdf..fefdb271 100644 --- a/cmd/collect_signals/worker.go +++ b/cmd/collect_signals/worker.go @@ -8,8 +8,12 @@ import ( "net/url" "os" + githubstats "github.com/ossf/scorecard/v4/clients/githubrepo/stats" "github.com/ossf/scorecard/v4/cron/data" + "github.com/ossf/scorecard/v4/cron/monitoring" "github.com/ossf/scorecard/v4/cron/worker" + "github.com/ossf/scorecard/v4/stats" + "go.opencensus.io/stats/view" "go.uber.org/zap" "github.com/ossf/criticality_score/internal/collector" @@ -21,6 +25,7 @@ const collectionDateColumnName = "collection_date" type collectWorker struct { logger *zap.Logger + exporter monitoring.Exporter c *collector.Collector s *scorer.Scorer scoreColumnName string @@ -110,6 +115,16 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq return nil } +// Close is called to clean up resources used by the worker. +func (w *collectWorker) Close() { + w.exporter.StopMetricsExporter() +} + +// PostProcess implements the worker.Worker interface. +func (w *collectWorker) PostProcess() { + w.exporter.Flush() +} + func getScorer(logger *zap.Logger, scoringEnabled bool, scoringConfigFile string) (*scorer.Scorer, error) { logger.Debug("Creating scorer") @@ -136,6 +151,25 @@ func getScorer(logger *zap.Logger, scoringEnabled bool, scoringConfigFile string return s, nil } +func getMetricsExporter() (monitoring.Exporter, error) { + exporter, err := monitoring.GetExporter() + if err != nil { + return nil, fmt.Errorf("getting monitoring exporter: %w", err) + } + if err := exporter.StartMetricsExporter(); err != nil { + return nil, fmt.Errorf("starting exporter: %w", err) + } + + if err := view.Register( + &stats.CheckRuntime, + &stats.CheckErrorCount, + &stats.OutgoingHTTPRequests, + &githubstats.GithubTokens); err != nil { + return nil, fmt.Errorf("opencensus view register: %w", err) + } + return exporter, nil +} + func NewWorker(ctx context.Context, logger *zap.Logger, writerType signalio.WriterType, scoringEnabled bool, scoringConfigFile, scoringColumn string, collectOpts []collector.Option) (*collectWorker, error) { logger.Info("Initializing worker") @@ -155,14 +189,17 @@ func NewWorker(ctx context.Context, logger *zap.Logger, writerType signalio.Writ scoringColumn = s.Name() } + exporter, err := getMetricsExporter() + if err != nil { + return nil, fmt.Errorf("metrics exporter: %w", err) + } + return &collectWorker{ logger: logger, c: c, s: s, scoreColumnName: scoringColumn, writerType: writerType, + exporter: exporter, }, nil } - -// PostProcess implements the worker.Worker interface. -func (w *collectWorker) PostProcess() {} diff --git a/go.mod b/go.mod index 185c46ba..c1811b52 100644 --- a/go.mod +++ b/go.mod @@ -9,10 +9,11 @@ require ( github.com/google/go-cmp v0.5.9 github.com/google/go-github/v47 v47.1.0 github.com/iancoleman/strcase v0.2.0 - github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa + github.com/ossf/scorecard/v4 v4.8.1-0.20221113231904-ca55bd0e67ea github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 + go.opencensus.io v0.23.0 go.uber.org/zap v1.23.0 - gocloud.dev v0.27.0 + gocloud.dev v0.26.0 google.golang.org/api v0.102.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -22,8 +23,11 @@ require ( cloud.google.com/go/compute v1.12.1 // indirect cloud.google.com/go/compute/metadata v0.2.1 // indirect cloud.google.com/go/iam v0.5.0 // indirect + cloud.google.com/go/monitoring v1.4.0 // indirect cloud.google.com/go/pubsub v1.26.0 // indirect cloud.google.com/go/storage v1.27.0 // indirect + cloud.google.com/go/trace v1.2.0 // indirect + contrib.go.opencensus.io/exporter/stackdriver v0.13.12 // indirect github.com/aws/aws-sdk-go v1.44.68 // indirect github.com/aws/aws-sdk-go-v2 v1.16.8 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 // indirect @@ -46,6 +50,7 @@ require ( github.com/benbjohnson/clock v1.1.0 // indirect github.com/bombsimon/logrusr/v2 v2.0.1 // indirect github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 // indirect + github.com/census-instrumentation/opencensus-proto v0.3.0 // indirect github.com/go-logr/logr v1.2.3 // indirect github.com/golang-jwt/jwt/v4 v4.4.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect @@ -59,17 +64,18 @@ require ( github.com/googleapis/gax-go/v2 v2.6.0 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect github.com/jszwec/csvutil v1.7.1 // indirect + github.com/kr/pretty v0.3.0 // indirect + github.com/prometheus/prometheus v2.5.0+incompatible // indirect github.com/rogpeppe/go-internal v1.8.1 // indirect github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a // indirect github.com/sirupsen/logrus v1.9.0 // indirect - go.opencensus.io v0.23.0 // indirect go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.1.0 // indirect + golang.org/x/net v0.2.0 // indirect golang.org/x/oauth2 v0.1.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.1.0 // indirect + golang.org/x/sys v0.2.0 // indirect golang.org/x/text v0.4.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index c061aceb..611a9ae1 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,3 @@ -bazil.org/fuse v0.0.0-20160811212531-371fbbdaa898/go.mod h1:Xbm+BRKSBEpa4q4hTSxohYNQpsxXPbPry4JJWOB3LB8= -bazil.org/fuse v0.0.0-20200407214033-5883e5a4b512/go.mod h1:FbcW6z/2VytnFDhZfumh8Ss8zxHE6qpMP5sHTRe0EaM= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -31,9 +29,6 @@ cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Ud cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.1/go.mod h1:fs4QogzfH5n2pBXBP9vRiU+eCny7lD2vmFZy79Iuw1U= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= -cloud.google.com/go v0.102.0/go.mod h1:oWcCzKlqJ5zgHQt9YsaeTY9KzIvjyy0ArmiBUgpQ+nc= -cloud.google.com/go v0.102.1/go.mod h1:XZ77E9qnTEnrgEOvr4xzfdX5TRo7fB4T2F4O6+34hIU= -cloud.google.com/go v0.103.0/go.mod h1:vwLx1nqLrzLX/fpwSMOXmFIqBOyHsvHbnAdbGSJ+mKk= cloud.google.com/go v0.104.0 h1:gSmWO7DY1vOm0MVU6DNXM11BWHHsTUmsC5cv1fuW5X8= cloud.google.com/go v0.104.0/go.mod h1:OO6xxXdJyvuJPcEPBLN9BJPD+jep5G1+2U5B5gkRYtA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= @@ -45,11 +40,9 @@ cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM7 cloud.google.com/go/bigquery v1.43.0 h1:u0fvz5ysJBe1jwUPI4LuPwAX+o+6fCUwf3ECeg6eDUQ= cloud.google.com/go/bigquery v1.43.0/go.mod h1:ZMQcXHsl+xmU1z36G2jNGZmKp9zNY5BUua5wDgmNCfw= cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTBXtfbBFow= +cloud.google.com/go/compute v1.2.0/go.mod h1:xlogom/6gr8RJGBe7nT2eGsQYAFUbbv8dbC29qE3Xmw= cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= -cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= -cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= -cloud.google.com/go/compute v1.7.0/go.mod h1:435lt8av5oL9P3fv1OEzSbSUe+ybHXGMPQHHZWZxy9U= cloud.google.com/go/compute v1.12.1 h1:gKVJMEyqV5c/UnpzjjQbo3Rjvvqpr9B1DFSbJC4OXr0= cloud.google.com/go/compute v1.12.1/go.mod h1:e8yNOBcBONZU1vJKCvCoDw/4JQsA0dpM4x/6PIIOocU= cloud.google.com/go/compute/metadata v0.2.1 h1:efOwf5ymceDhK6PKMnnrTHP4pppY5L22mle96M1yP48= @@ -57,257 +50,157 @@ cloud.google.com/go/compute/metadata v0.2.1/go.mod h1:jgHgmJd2RKBGzXqF5LR2EZMGxB cloud.google.com/go/datacatalog v1.6.0 h1:xzXGAE2fAuMh+ksODKr9nRv9ega1vHjFwRqMA8tRrVE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= cloud.google.com/go/firestore v1.6.1/go.mod h1:asNXNOzBdyVQmEU+ggO8UPodTkEVFW5Qx+rwHnAz+EY= cloud.google.com/go/iam v0.1.0/go.mod h1:vcUNEa0pEm0qRVpmWepWaFMIAI8/hjB9mO8rNCJtF6c= +cloud.google.com/go/iam v0.1.1/go.mod h1:CKqrcnI/suGpybEHxZ7BMehL0oA4LpdyJdUlTl9jVMw= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/iam v0.5.0 h1:fz9X5zyTWBmamZsqvqZqD7khbifcZF/q+Z1J8pfhIUg= cloud.google.com/go/iam v0.5.0/go.mod h1:wPU9Vt0P4UmCux7mqtRu6jcpPAb74cP1fh50J3QpkUc= +cloud.google.com/go/kms v1.1.0/go.mod h1:WdbppnCDMDpOvoYBMn1+gNmOeEoZYqAv+HeuKARGCXI= cloud.google.com/go/kms v1.4.0/go.mod h1:fajBHndQ+6ubNw6Ss2sSd+SWvjL26RNo/dr7uxsnnOA= cloud.google.com/go/monitoring v1.1.0/go.mod h1:L81pzz7HKn14QCMaCs6NTQkdBnE87TElyanS95vIcl4= -cloud.google.com/go/monitoring v1.5.0/go.mod h1:/o9y8NYX5j91JjD/JvGLYbi86kL11OjyJXq2XziLJu4= +cloud.google.com/go/monitoring v1.4.0 h1:05+IuNMbh40hbxcqQ4SnynbwZbLG1Wc9dysIJxnfv7U= +cloud.google.com/go/monitoring v1.4.0/go.mod h1:y6xnxfwI3hTFWOdkOaD7nfJVlwuC3/mS/5kvtT131p4= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/pubsub v1.24.0/go.mod h1:rWv09Te1SsRpRGPiWOMDKraMQTJyJps4MkUCoMGUgqw= +cloud.google.com/go/pubsub v1.19.0/go.mod h1:/O9kmSe9bb9KRnIAWkzmqhPjHo6LtzGOBYd/kr06XSs= cloud.google.com/go/pubsub v1.26.0 h1:Y/HcMxVXgkUV2pYeLMUkclMg0ue6U0jVyI5xEARQ4zA= cloud.google.com/go/pubsub v1.26.0/go.mod h1:QgBH3U/jdJy/ftjPhTkyXNj543Tin1pRYcdcPRnFIRI= -cloud.google.com/go/secretmanager v1.5.0/go.mod h1:5C9kM+RwSpkURNovKySkNvGQLUaOgyoR5W0RUx2SyHQ= +cloud.google.com/go/secretmanager v1.3.0/go.mod h1:+oLTkouyiYiabAQNugCeTS3PAArGiMJuBqvJnJsyH+U= cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= -cloud.google.com/go/storage v1.23.0/go.mod h1:vOEEDNFnciUMhBeT6hsJIn3ieU5cFRmzeLgDvXzfIXc= -cloud.google.com/go/storage v1.24.0/go.mod h1:3xrJEFMXBsQLgxwThyjuD3aYlroL0TMRec1ypGUQ0KE= +cloud.google.com/go/storage v1.21.0/go.mod h1:XmRlxkgPjlBONznT2dDUU/5XlpU2OjMnKuqnZI01LAA= cloud.google.com/go/storage v1.27.0 h1:YOO045NZI9RKfCj1c5A/ZtuuENUc8OAW+gHdGnDgyMQ= cloud.google.com/go/storage v1.27.0/go.mod h1:x9DOL8TK/ygDUMieqwfhdpQryTeEkhGKMi80i/iqR2s= cloud.google.com/go/trace v1.0.0/go.mod h1:4iErSByzxkyHWzzlAj63/Gmjz0NH1ASqhJguHpGcr6A= +cloud.google.com/go/trace v1.2.0 h1:oIaB4KahkIUOpLSAAjEJ8y2desbjY/x/RfP4O3KAtTI= cloud.google.com/go/trace v1.2.0/go.mod h1:Wc8y/uYyOhPy12KEnXG9XGrvfMz5F5SrYecQlbW1rwM= -code.cloudfoundry.org/clock v0.0.0-20180518195852-02e53af36e6c/go.mod h1:QD9Lzhd/ux6eNQVUDVRJX/RKTigpewimNYBi7ivZKY8= contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= -contrib.go.opencensus.io/exporter/stackdriver v0.13.13/go.mod h1:5pSSGY0Bhuk7waTHuDf4aQ8D2DrhgETRo9fy6k3Xlzc= +contrib.go.opencensus.io/exporter/stackdriver v0.13.10/go.mod h1:I5htMbyta491eUxufwwZPQdcKvvgzMB4O9ni41YnIM8= +contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY= +contrib.go.opencensus.io/exporter/stackdriver v0.13.12/go.mod h1:mmxnWlrvrFdpiOHOhxBaVi1rkc0WOqhgfknj4Yg0SeQ= contrib.go.opencensus.io/integrations/ocsql v0.1.7/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8/go.mod h1:CzsSbkDixRphAF5hS6wbMKq0eI6ccJRb7/A0M6JBnwg= -github.com/Azure/azure-amqp-common-go/v3 v3.2.3/go.mod h1:7rPmbSfszeovxGfc5fSAXE4ehlXQZHpMja2OtxC2Tas= -github.com/Azure/azure-sdk-for-go v16.2.1+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v63.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v65.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= -github.com/Azure/azure-sdk-for-go v66.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-amqp-common-go/v3 v3.2.1/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= +github.com/Azure/azure-amqp-common-go/v3 v3.2.2/go.mod h1:O6X1iYHP7s2x7NjUKsXVhkwWrQhxrd+d8/3rRadj4CI= +github.com/Azure/azure-pipeline-go v0.2.3 h1:7U9HBg1JFK3jHl5qmo4CTZKFTVgMwdFHMVtCdfBE21U= +github.com/Azure/azure-pipeline-go v0.2.3/go.mod h1:x841ezTBIMG6O3lAcl8ATHnsOPVl2bqk7S3ta6S6u4k= +github.com/Azure/azure-sdk-for-go v51.1.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= +github.com/Azure/azure-sdk-for-go v59.3.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc= github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0/go.mod h1:h6H6c8enJmmocHUbLiiGY6sx7f9i+X3m1CHdd5c6Rdw= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.0.0/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.1.1/go.mod h1:uGG2W01BaETf0Ozp+QxxKJdMBNRWPdstHG0Fmdwn1/U= github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0/go.mod h1:HcM1YX14R7CJcghJGOYCgdezslRSVzqwLf/q+4Y2r/0= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.0.0/go.mod h1:+6sju8gk8FRmSajX3Oz4G5Gm7P+mbqE9FVaXXFYTkCM= github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2TzfVZ1pCb5vxm4BtZPUdYWe/Xo8= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.0.0/go.mod h1:eWRD7oawr1Mu1sLCawqVc0CUiF43ia3qQMxLscsKQ9w= -github.com/Azure/azure-sdk-for-go/sdk/messaging/azservicebus v1.0.2/go.mod h1:LH9XQnMr2ZYxQdVdCrzLO9mxeDyrDFa6wbSI3x5zCZk= -github.com/Azure/azure-sdk-for-go/sdk/storage/azblob v0.4.1/go.mod h1:eZ4g6GUvXiGulfIbbhh1Xr4XwUYaYaWMqzGD/284wCA= -github.com/Azure/go-amqp v0.17.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= -github.com/Azure/go-amqp v0.17.5/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= -github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210608223527-2377c96fe795/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8= -github.com/Azure/go-ansiterm v0.0.0-20210617225240-d185dfc1b5a1/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E= -github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= +github.com/Azure/azure-service-bus-go v0.11.5/go.mod h1:MI6ge2CuQWBVq+ly456MY7XqNLJip5LO1iSFodbNLbU= +github.com/Azure/azure-storage-blob-go v0.14.0 h1:1BCg74AmVdYwO3dlKwtFU1V0wU2PZdREkXvAmZJRUlM= +github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck= +github.com/Azure/go-amqp v0.16.0/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= +github.com/Azure/go-amqp v0.16.4/go.mod h1:9YJ3RhxRT1gquYnzpZO1vcYMMpAdJT+QEg6fwmw9Zlg= github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24= -github.com/Azure/go-autorest/autorest v0.11.1/go.mod h1:JFgpikqFJ/MleTTxwepExTKnFUKKszPS8UavbQYUMuw= github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= -github.com/Azure/go-autorest/autorest v0.11.24/go.mod h1:G6kyRlFnTuSbEYkQGawPfsCswgme4iYf6rfSKUDzbCc= -github.com/Azure/go-autorest/autorest v0.11.25/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= -github.com/Azure/go-autorest/autorest v0.11.27/go.mod h1:7l8ybrIdUmGqZMTD0sRtAr8NvbHjfofbf8RSP2q7w7U= -github.com/Azure/go-autorest/autorest v0.11.28/go.mod h1:MrkzG3Y3AH668QyF9KRk5neJnGgmhQ6krbhR8Q5eMvA= -github.com/Azure/go-autorest/autorest/adal v0.9.0/go.mod h1:/c022QCutn2P7uY+/oQWWNcK9YU+MH96NgK+jErpbcg= +github.com/Azure/go-autorest/autorest v0.11.19/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA= +github.com/Azure/go-autorest/autorest v0.11.22/go.mod h1:BAWYUWGPEtKPzjVkp0Q6an0MJcJDsoh5Z1BFAEFs4Xs= github.com/Azure/go-autorest/autorest/adal v0.9.5/go.mod h1:B7KF7jKIeC9Mct5spmyCB/A8CG/sEz1vwIRGv/bbw7A= github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= -github.com/Azure/go-autorest/autorest/adal v0.9.18/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.20/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= -github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U= -github.com/Azure/go-autorest/autorest/azure/auth v0.5.11/go.mod h1:84w/uV8E37feW2NCJ08uT9VBfjfUHpgLVnG2InYD6cg= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.5/go.mod h1:ADQAXrkgm7acgWVUNamOgh8YNrv4p27l3Wc55oVfpzg= -github.com/Azure/go-autorest/autorest/azure/cli v0.4.6/go.mod h1:piCfgPho7BiIDdEQ1+g4VmKyD5y+p/XtSNqE6Hc4QD0= +github.com/Azure/go-autorest/autorest/adal v0.9.14/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M= +github.com/Azure/go-autorest/autorest/adal v0.9.17/go.mod h1:XVVeme+LZwABT8K5Lc3hA4nAe8LDBVle26gTrguhhPQ= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.9/go.mod h1:hg3/1yw0Bq87O3KvvnJoAh34/0zbP7SFizX/qN5JvjU= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2/go.mod h1:7qkJkT+j6b+hIpzMOwPChJhTqS8VbsqqgULzMNRugoM= github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74= -github.com/Azure/go-autorest/autorest/mocks v0.4.0/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k= -github.com/Azure/go-autorest/autorest/mocks v0.4.2/go.mod h1:Vy7OitM9Kei0i1Oj+LvyAWMXJHeKH1MVlzFugfVrmyU= github.com/Azure/go-autorest/autorest/to v0.4.0/go.mod h1:fE8iZBn7LQR7zH/9XU2NcPR4o9jEImooCeWJcYV/zLE= github.com/Azure/go-autorest/autorest/validation v0.3.1/go.mod h1:yhLgjC0Wda5DYXl6JAsWyUe4KVNffhoDhG0zVzUMo3E= -github.com/Azure/go-autorest/logger v0.2.0/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8= github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU= -github.com/AzureAD/microsoft-authentication-library-for-go v0.4.0/go.mod h1:Vt9sXTKwMyGcOxSmLDMnGPgqsUg7m8pe215qMLrDXw4= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= -github.com/GoogleCloudPlatform/cloudsql-proxy v1.31.2/go.mod h1:qR6jVnZTKDCW3j+fC9mOEPHm++1nKDMkqbbkD6KNsfo= -github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0/go.mod h1:spvB9eLJH9dutlbPSRmHvSXXHOwGRyeXh1jVdquA2G8= github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= -github.com/Microsoft/go-winio v0.4.11/go.mod h1:VhR8bwka0BXejwEJY73c50VrPtXAaKcyvVC4A4RozmA= -github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= -github.com/Microsoft/go-winio v0.4.15-0.20190919025122-fc70bd9a86b5/go.mod h1:tTuCMEN+UleMWgg9dVx4Hu52b1bJo+59jBh3ajtinzw= -github.com/Microsoft/go-winio v0.4.16-0.20201130162521-d1ffc52c7331/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= -github.com/Microsoft/go-winio v0.4.17-0.20210211115548-6eac466e5fa3/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.4.17-0.20210324224401-5516f17a5958/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.4.17/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/go-winio v0.5.1/go.mod h1:JPGBdM1cNvN/6ISo+n8V5iA4v8pBzdOpzfwIujj1a84= -github.com/Microsoft/hcsshim v0.8.6/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.7-0.20190325164909-8abdbb8205e4/go.mod h1:Op3hHsoHPAvb6lceZHDtd9OkTew38wNoXnJs8iY7rUg= -github.com/Microsoft/hcsshim v0.8.7/go.mod h1:OHd7sQqRFrYd3RmSgbgji+ctCwkbq2wbEYNSzOYtcBQ= -github.com/Microsoft/hcsshim v0.8.9/go.mod h1:5692vkUqntj1idxauYlpoINNKeqCiG6Sg38RRsjT5y8= -github.com/Microsoft/hcsshim v0.8.14/go.mod h1:NtVKoYxQuTLx6gEq0L96c9Ju4JbRJ4nY2ow3VK6a9Lg= -github.com/Microsoft/hcsshim v0.8.15/go.mod h1:x38A4YbHbdxJtc0sF6oIz+RG0npwSCAvn69iY6URG00= -github.com/Microsoft/hcsshim v0.8.16/go.mod h1:o5/SZqmR7x9JNKsW3pu+nqHm0MF8vbA+VxGOoXdC600= -github.com/Microsoft/hcsshim v0.8.20/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.8.21/go.mod h1:+w2gRZ5ReXQhFOrvSQeNfhrYB/dg3oDwTOcER2fw4I4= -github.com/Microsoft/hcsshim v0.8.23/go.mod h1:4zegtUJth7lAvFyc6cH2gGQ5B3OFQim01nnU2M8jKDg= -github.com/Microsoft/hcsshim v0.9.2/go.mod h1:7pLA8lDk46WKDWlVsENo92gC0XFa8rbKfyFRBqxEbCc= -github.com/Microsoft/hcsshim/test v0.0.0-20201218223536-d3e5debf77da/go.mod h1:5hlzMzRKMLyo42nCZ9oml8AdTlq/0cvIaBv6tK1RehU= -github.com/Microsoft/hcsshim/test v0.0.0-20210227013316-43a75bb4edd3/go.mod h1:mw7qgWloBUl75W/gVH3cQszUg1+gUITj7D6NY7ywVnY= -github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= -github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= -github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/Shopify/logrus-bugsnag v0.0.0-20171204204709-577dee27f20d/go.mod h1:HI8ITrYtUY+O+ZhtlqUnD8+KwNPOyugEhfP9fdUIaEQ= -github.com/Shopify/sarama v1.19.0/go.mod h1:FVkBWblsNy7DGZRfXLU0O9RCGt5g3g3yEuWXgklEdEo= -github.com/Shopify/toxiproxy v2.1.4+incompatible/go.mod h1:OXgGpZ6Cli1/URJOF1DMxUHB2q5Ap20/P/eIdh4G0pI= -github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/4+TcAqDqk/vUH7g= -github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= -github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae/go.mod h1:CgnQgUtFrFz9mxFNtED3jI5tLDjKlOM+oUF/sTk6ps0= -github.com/alexflint/go-filemutex v1.1.0/go.mod h1:7P4iRhttt/nUvUOrYIhcpMzv2G6CY9UnI16Z+UJqRyk= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/apache/thrift v0.13.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ= -github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o= -github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= -github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= -github.com/armon/go-metrics v0.3.3/go.mod h1:4O98XIr/9W0sxpJ8UaYkvjk10Iff7SnFrb4QAOwNTFc= -github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= -github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= -github.com/aryann/difflib v0.0.0-20170710044230-e206f873d14a/go.mod h1:DAHtR1m6lCRdSC2Tm3DSWRPvIPr6xNKyeHdqDQSQT+A= -github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= -github.com/aws/aws-sdk-go v1.15.11/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= -github.com/aws/aws-sdk-go v1.27.0/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= -github.com/aws/aws-sdk-go v1.38.35/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= -github.com/aws/aws-sdk-go v1.43.11/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/aws/aws-sdk-go v1.37.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro= github.com/aws/aws-sdk-go v1.43.31/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go v1.44.45/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/aws/aws-sdk-go v1.44.68 h1:7zNr5+HLG0TMq+ZcZ8KhT4eT2KyL7v+u7/jANKEIinM= github.com/aws/aws-sdk-go v1.44.68/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= -github.com/aws/aws-sdk-go-v2 v0.18.0/go.mod h1:JWVYvqSMppoMJC0x5wdwiImzgXTI9FuZwxzkQq9wy+g= +github.com/aws/aws-sdk-go-v2 v1.16.2/go.mod h1:ytwTPBG6fXTZLxxeeCCWj2/EMYp/xDUgX+OET6TLNNU= github.com/aws/aws-sdk-go-v2 v1.16.8 h1:gOe9UPR98XSf7oEJCcojYg+N2/jCRm4DdeIsP85pIyQ= github.com/aws/aws-sdk-go-v2 v1.16.8/go.mod h1:6CpKuLXg2w7If3ABZCl/qZ6rEgwtjZTn4eAf4RcEyuw= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.1/go.mod h1:n8Bs1ElDD2wJ9kCRTczA83gYbBmjSwZp3umc6zF4EeM= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3 h1:S/ZBwevQkr7gv5YxONYpGQxlMFFYSRfz3RMcjsC9Qhk= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.3/go.mod h1:gNsR5CaXKmQSSzrmGxmwmct/r+ZBfbxorAuXYsj/M5Y= +github.com/aws/aws-sdk-go-v2/config v1.15.3/go.mod h1:9YL3v07Xc/ohTsxFXzan9ZpFpdTOFl4X65BAKYaz8jg= github.com/aws/aws-sdk-go-v2/config v1.15.15 h1:yBV+J7Au5KZwOIrIYhYkTGJbifZPCkAnCFSvGsF3ui8= github.com/aws/aws-sdk-go-v2/config v1.15.15/go.mod h1:A1Lzyy/o21I5/s2FbyX5AevQfSVXpvvIDCoVFD0BC4E= +github.com/aws/aws-sdk-go-v2/credentials v1.11.2/go.mod h1:j8YsY9TXTm31k4eFhspiQicfXPLZ0gYXA50i4gxPE8g= github.com/aws/aws-sdk-go-v2/credentials v1.12.10 h1:7gGcMQePejwiKoDWjB9cWnpfVdnz/e5JwJFuT6OrroI= github.com/aws/aws-sdk-go-v2/credentials v1.12.10/go.mod h1:g5eIM5XRs/OzIIK81QMBl+dAuDyoLN0VYaLP+tBqEOk= +github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.3/go.mod h1:uk1vhHHERfSVCUnqSqz8O48LBYDSC+k6brng09jcMOk= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9 h1:hz8tc+OW17YqxyFFPSkvfSikbqWcyyHRyPVSTzC0+aI= github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.12.9/go.mod h1:KDCCm4ONIdHtUloDcFvK2+vshZvx4Zmj7UMDfusuz5s= +github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.3/go.mod h1:0dHuD2HZZSiwfJSy1FO5bX1hQ1TxVV1QXXjpn3XUE44= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21 h1:bpiKFJ9aC0xTVpygSRRRL/YHC1JZ+pHQHENATHuoiwo= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.11.21/go.mod h1:iIYPrQ2rYfZiB/iADYlhj9HHZ9TTi6PqKQPAqygohbE= +github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.9/go.mod h1:AnVH5pvai0pAF4lXRq0bmhbes1u9R8wTE+g+183bZNM= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15 h1:bx5F2mr6H6FC7zNIQoDoUr8wEKnvmwRncujT3FYRtic= github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.15/go.mod h1:pWrr2OoHlT7M/Pd2y4HV3gJyPb3qj5qMmnPkKSNPYK4= +github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.3/go.mod h1:ssOhaLpRlh88H3UmEcsBoVKq309quMvm3Ds8e9d4eJM= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9 h1:5sbyznZC2TeFpa4fvtpvpcGbzeXEEs1l1Jo51ynUNsQ= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.9/go.mod h1:08tUpeSGN33QKSO7fwxXczNfiwCpbj+GxK6XKwqWVv0= +github.com/aws/aws-sdk-go-v2/internal/ini v1.3.10/go.mod h1:8DcYQcz0+ZJaSxANlHIsbbi6S+zMwjwdDqwW3r9AzaE= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.16 h1:f0ySVcmQhwmzn7zQozd8wBM3yuGBfzdpsOaKQ0/Epzw= github.com/aws/aws-sdk-go-v2/internal/ini v1.3.16/go.mod h1:CYmI+7x03jjJih8kBEEFKRQc40UjUokT0k7GbvrhhTc= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6 h1:3L8pcjvgaSOs0zzZcMKzxDSkYKEpwJ2dNVDdxm68jAY= github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.6/go.mod h1:O7Oc4peGZDEKlddivslfYFvAbgzvl/GH3J8j3JIGBXc= +github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.1/go.mod h1:GeUru+8VzrTXV/83XyMJ80KpH8xO89VPoUileyNQ+tc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3 h1:4n4KCtv5SUoT5Er5XV41huuzrCqepxlW3SDI9qHQebc= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.9.3/go.mod h1:gkb2qADY+OHaGLKNTYxMaQNacfeyQpZ4csDTQMeFmcw= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.3/go.mod h1:Seb8KNmD6kVTjwRjVEgOT5hPin6sq+v4C2ycJQDwuH8= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10 h1:7LJcuRalaLw+GYQTMGmVUl4opg2HrDZkvn/L3KvIQfw= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.10/go.mod h1:Qks+dxK3O+Z2deAhNo6cJ8ls1bam3tUGUAcgxQP1c70= +github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.3/go.mod h1:wlY6SVjuwvh3TVRpTqdy4I1JpBFLX4UGeKZdWntaocw= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.9 h1:sHfDuhbOuuWSIAEDd3pma6p0JgUcR2iePxtCE8gfCxQ= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.9/go.mod h1:yQowTpvdZkFVuHrLBXmczat4W+WJKg/PafBZnGBLga0= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.3/go.mod h1:Bm/v2IaN6rZ+Op7zX+bOUMdL4fsrYZiD0dsjLhNKwZc= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9 h1:sJdKvydGYDML9LTFcp6qq6Z5fIjN0Rdq2Gvw1hUg8tc= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.13.9/go.mod h1:Rc5+wn2k8gFSi3V1Ch4mhxOzjMh+bYSXVFfVaqowQOY= -github.com/aws/aws-sdk-go-v2/service/kms v1.18.1/go.mod h1:4PZMUkc9rXHWGVB5J9vKaZy3D7Nai79ORworQ3ASMiM= +github.com/aws/aws-sdk-go-v2/service/kms v1.16.3/go.mod h1:QuiHPBqlOFCi4LqdSskYYAWpQlx3PKmohy+rE2F+o5g= +github.com/aws/aws-sdk-go-v2/service/s3 v1.26.3/go.mod h1:g1qvDuRsJY+XghsV6zg00Z4KJ7DtFFCx8fJD2a491Ak= github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2 h1:NvzGue25jKnuAsh6yQ+TZ4ResMcnp49AWgWGm2L4b5o= github.com/aws/aws-sdk-go-v2/service/s3 v1.27.2/go.mod h1:u+566cosFI+d+motIz3USXEh6sN8Nq4GrNXSg2RXVMo= -github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.14/go.mod h1:xakbH8KMsQQKqzX87uyyzTHshc/0/Df8bsTneTS5pFU= -github.com/aws/aws-sdk-go-v2/service/sns v1.17.10/go.mod h1:uITsRNVMeCB3MkWpXxXw0eDz8pW4TYLzj+eyQtbhSxM= -github.com/aws/aws-sdk-go-v2/service/sqs v1.19.1/go.mod h1:A94o564Gj+Yn+7QO1eLFeI7UVv3riy/YBFOfICVqFvU= -github.com/aws/aws-sdk-go-v2/service/ssm v1.27.6/go.mod h1:fiFzQgj4xNOg4/wqmAiPvzgDMXPD+cUEplX/CYn+0j0= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4/go.mod h1:PJc8s+lxyU8rrre0/4a0pn2wgwiDvOEzoOjcJUBr67o= +github.com/aws/aws-sdk-go-v2/service/sns v1.17.4/go.mod h1:kElt+uCcXxcqFyc+bQqZPFD9DME/eC6oHBXvFzQ9Bcw= +github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3/go.mod h1:skmQo0UPvsjsuYYSYMVmrPc1HWCbHUJyrCEp+ZaLzqM= +github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1/go.mod h1:NR/xoKjdbRJ+qx0pMR4mI+N/H1I1ynHwXnO6FowXJc0= +github.com/aws/aws-sdk-go-v2/service/sso v1.11.3/go.mod h1:7UQ/e69kU7LDPtY40OyoHYgRmgfGM4mgsLYtcObdveU= github.com/aws/aws-sdk-go-v2/service/sso v1.11.13 h1:DQpf+al+aWozOEmVEdml67qkVZ6vdtGUi71BZZWw40k= github.com/aws/aws-sdk-go-v2/service/sso v1.11.13/go.mod h1:d7ptRksDDgvXaUvxyHZ9SYh+iMDymm94JbVcgvSYSzU= +github.com/aws/aws-sdk-go-v2/service/sts v1.16.3/go.mod h1:bfBj0iVmsUyUg4weDB4NxktD9rDGeKSVWnjTnwbx9b8= github.com/aws/aws-sdk-go-v2/service/sts v1.16.10 h1:7tquJrhjYz2EsCBvA9VTl+sBAAh1bv7h/sGASdZOGGo= github.com/aws/aws-sdk-go-v2/service/sts v1.16.10/go.mod h1:cftkHYN6tCDNfkSasAmclSfl4l7cySoay8vz7p/ce0E= +github.com/aws/smithy-go v1.11.2/go.mod h1:3xHYmszWVx2c0kIwQeEVf9uSm4fYZt67FBJnwub1bgM= github.com/aws/smithy-go v1.12.0 h1:gXpeZel/jPoWQ7OEmLIgCUnhkFftqNfwWUwAHSlp1v0= github.com/aws/smithy-go v1.12.0/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= -github.com/benbjohnson/clock v1.0.3/go.mod h1:bGMdMPoPVvcYyt1gHDf4J2KE153Yf9BuiUKYMaxlTDM= github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= -github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= -github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= -github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= -github.com/bitly/go-simplejson v0.5.0/go.mod h1:cXHtHw4XUPsvGaxgjIAn8PhEWG9NfngEKAMDJEczWVA= -github.com/bits-and-blooms/bitset v1.2.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= -github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= -github.com/blang/semver v3.1.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= -github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/blendle/zapdriver v1.3.1 h1:C3dydBOWYRiOk+B8X9IVZ5IOe+7cl+tGOexN4QqHfpE= github.com/blendle/zapdriver v1.3.1/go.mod h1:mdXfREi6u5MArG4j9fewC+FGnXaBR+T4Ox4J2u4eHCc= -github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dRnpXw/yCqJaO+ZrUyxD+3VXMFFr56k5XYrpB4= github.com/bombsimon/logrusr/v2 v2.0.1 h1:1VgxVNQMCvjirZIYaT9JYn6sAVGVEcNtRE0y4mvaOAM= github.com/bombsimon/logrusr/v2 v2.0.1/go.mod h1:ByVAX+vHdLGAfdroiMg6q0zgq2FODY2lc5YJvzmOJio= github.com/bradleyfalzon/ghinstallation/v2 v2.1.0 h1:5+NghM1Zred9Z078QEZtm28G/kfDfZN/92gkDlLwGVA= github.com/bradleyfalzon/ghinstallation/v2 v2.1.0/go.mod h1:Xg3xPRN5Mcq6GDqeUVhFbjEWMb4JHCyWEeeBGEYQoTU= -github.com/bshuster-repo/logrus-logstash-hook v0.4.1/go.mod h1:zsTqEiSzDgAa/8GZR7E1qaXrhYNDKBYy5/dWPTIflbk= -github.com/buger/jsonparser v0.0.0-20180808090653-f4dd9f5a6b44/go.mod h1:bbYlZJ7hK1yFx9hf58LP0zeX7UjIGs20ufpu3evjr+s= -github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0= -github.com/bugsnag/bugsnag-go v0.0.0-20141110184014-b1d153021fcd/go.mod h1:2oa8nejYd4cQ/b0hMIopN0lCRxU0bueqREvZLWFrtK8= -github.com/bugsnag/osext v0.0.0-20130617224835-0dd3f918b21b/go.mod h1:obH5gd0BsqsP2LwDJ9aOkm/6J86V6lyAXCoQWGw3K50= -github.com/bugsnag/panicwrap v0.0.0-20151223152923-e2c28503fcd0/go.mod h1:D/8v3kj0zr8ZAKg1AQ6crr+5VwKN5eIywRkfhyM/+dE= -github.com/casbin/casbin/v2 v2.1.2/go.mod h1:YcPU1XXisHhLzuxH9coDNf2FbKpjGlbCg3n9yuLkIJQ= -github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM= -github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.2/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= -github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/census-instrumentation/opencensus-proto v0.3.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= -github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/checkpoint-restore/go-criu/v4 v4.1.0/go.mod h1:xUQBLp4RLc5zJtWY++yjOoMoB5lihDt7fai+75m+rGw= -github.com/checkpoint-restore/go-criu/v5 v5.0.0/go.mod h1:cfwC0EG7HMUenopBsUf9d89JlCLQIfgVcNsNN0t6T2M= -github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/logex v1.2.0/go.mod h1:9+9sk7u7pGNWYMkh0hdiL++6OeibzJccyQU4p4MedaY= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/readline v1.5.0/go.mod h1:x22KAscuvRqlLoK9CsoYsmxoXZMMFVyOl86cAH8qUic= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/chzyer/test v0.0.0-20210722231415-061457976a23/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/cilium/ebpf v0.0.0-20200110133405-4032b1d8aae3/go.mod h1:MA5e5Lr8slmEg9bt0VpxxWqJlO4iwu3FBdHUzV7wQVg= -github.com/cilium/ebpf v0.0.0-20200702112145-1c8d4c9ef775/go.mod h1:7cR51M8ViRLIdUjrmSXlK9pkrsDlLHbO8jiB8X8JnOc= -github.com/cilium/ebpf v0.2.0/go.mod h1:To2CFviqOWL/M0gIMsvSMlqe7em/l1ALkX1PyjrX2Qs= -github.com/cilium/ebpf v0.4.0/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.6.2/go.mod h1:4tRaxcgiL706VnOzHOdBlY8IEAIdxINsQBcU4xJJXRs= -github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA= -github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= -github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= -github.com/clbanning/x2j v0.0.0-20191024224557-825249438eec/go.mod h1:jMjuTZXRI4dUb/I5gc9Hdhagfvm9+RyrPryS/auMzxE= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= @@ -316,186 +209,21 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= -github.com/cncf/xds/go v0.0.0-20220314180256-7f1daf1720fc/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ= -github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= -github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= -github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= -github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= -github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= -github.com/containerd/aufs v0.0.0-20200908144142-dab0cbea06f4/go.mod h1:nukgQABAEopAHvB6j7cnP5zJ+/3aVcE7hCYqvIwAHyE= -github.com/containerd/aufs v0.0.0-20201003224125-76a6863f2989/go.mod h1:AkGGQs9NM2vtYHaUen+NljV0/baGCAPELGm2q9ZXpWU= -github.com/containerd/aufs v0.0.0-20210316121734-20793ff83c97/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= -github.com/containerd/aufs v1.0.0/go.mod h1:kL5kd6KM5TzQjR79jljyi4olc1Vrx6XBlcyj3gNv2PU= -github.com/containerd/btrfs v0.0.0-20201111183144-404b9149801e/go.mod h1:jg2QkJcsabfHugurUvvPhS3E08Oxiuh5W/g1ybB4e0E= -github.com/containerd/btrfs v0.0.0-20210316141732-918d888fb676/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= -github.com/containerd/btrfs v1.0.0/go.mod h1:zMcX3qkXTAi9GI50+0HOeuV8LU2ryCE/V2vG/ZBiTss= -github.com/containerd/cgroups v0.0.0-20190717030353-c4b9ac5c7601/go.mod h1:X9rLEHIqSf/wfK8NsPqxJmeZgW4pcfzdXITDrUSJ6uI= -github.com/containerd/cgroups v0.0.0-20190919134610-bf292b21730f/go.mod h1:OApqhQ4XNSNC13gXIwDjhOQxjWa/NxkwZXJ1EvqT0ko= -github.com/containerd/cgroups v0.0.0-20200531161412-0dbf7f05ba59/go.mod h1:pA0z1pT8KYB3TCXK/ocprsh7MAkoW8bZVzPdih9snmM= -github.com/containerd/cgroups v0.0.0-20200710171044-318312a37340/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= -github.com/containerd/cgroups v0.0.0-20200824123100-0b889c03f102/go.mod h1:s5q4SojHctfxANBDvMeIaIovkq29IP48TKAxnhYRxvo= -github.com/containerd/cgroups v0.0.0-20210114181951-8a68de567b68/go.mod h1:ZJeTFisyysqgcCdecO57Dj79RfL0LNeGiFUqLYQRYLE= -github.com/containerd/cgroups v1.0.1/go.mod h1:0SJrPIenamHDcZhEcJMNBB85rHcUsw4f25ZfBiPYRkU= -github.com/containerd/cgroups v1.0.3/go.mod h1:/ofk34relqNjSGyqPrmEULrO4Sc8LJhvJmWbUCUKqj8= -github.com/containerd/console v0.0.0-20180822173158-c12b1e7919c1/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20181022165439-0650fd9eeb50/go.mod h1:Tj/on1eG8kiEhd0+fhSDzsPAFESxzBBvdyEgyryXffw= -github.com/containerd/console v0.0.0-20191206165004-02ecf6a7291e/go.mod h1:8Pf4gM6VEbTNRIT26AyyU7hxdQU3MvAvxVI0sc00XBE= -github.com/containerd/console v1.0.1/go.mod h1:XUsP6YE/mKtz6bxc+I8UiKKTP04qjQL4qcS3XoQ5xkw= -github.com/containerd/console v1.0.2/go.mod h1:ytZPjGgY2oeTkAONYafi2kSj0aYggsf8acV1PGKCbzQ= -github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= -github.com/containerd/containerd v1.2.10/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0-beta.2.0.20190828155532-0293cbd26c69/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.0/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.1-0.20191213020239-082f7e3aed57/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.3.2/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.0-beta.2.0.20200729163537-40b22ef07410/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.1/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.3/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.4.9/go.mod h1:bC6axHOhabU15QhwfG7w5PipXdVtMXFTttgp+kVtyUA= -github.com/containerd/containerd v1.5.0-beta.1/go.mod h1:5HfvG1V2FsKesEGQ17k5/T7V960Tmcumvqn8Mc+pCYQ= -github.com/containerd/containerd v1.5.0-beta.3/go.mod h1:/wr9AVtEM7x9c+n0+stptlo/uBBoBORwEx6ardVcmKU= -github.com/containerd/containerd v1.5.0-beta.4/go.mod h1:GmdgZd2zA2GYIBZ0w09ZvgqEq8EfBp/m3lcVZIvPHhI= -github.com/containerd/containerd v1.5.0-rc.0/go.mod h1:V/IXoMqNGgBlabz3tHD2TWDoTJseu1FGOKuoA4nNb2s= -github.com/containerd/containerd v1.5.1/go.mod h1:0DOxVqwDy2iZvrZp2JUx/E+hS0UNTVn7dJnIOwtYR4g= -github.com/containerd/containerd v1.5.7/go.mod h1:gyvv6+ugqY25TiXxcZC3L5yOeYgEw0QMhscqVp1AR9c= -github.com/containerd/containerd v1.5.8/go.mod h1:YdFSv5bTFLpG2HIYmfqDpSYYTDX+mc5qtSuYx1YUb/s= -github.com/containerd/containerd v1.6.1/go.mod h1:1nJz5xCZPusx6jJU8Frfct988y0NpumIq9ODB0kLtoE= -github.com/containerd/continuity v0.0.0-20190426062206-aaeac12a7ffc/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20190815185530-f2a389ac0a02/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20191127005431-f65d91d395eb/go.mod h1:GL3xCUCBDV3CZiTSEKksMWbLE66hEyuu9qyDOOqM47Y= -github.com/containerd/continuity v0.0.0-20200710164510-efbc4488d8fe/go.mod h1:cECdGN1O8G9bgKTlLhuPJimka6Xb/Gg7vYzCTNVxhvo= -github.com/containerd/continuity v0.0.0-20201208142359-180525291bb7/go.mod h1:kR3BEg7bDFaEddKm54WSmrol1fKWDU1nKYkgrcgZT7Y= -github.com/containerd/continuity v0.0.0-20210208174643-50096c924a4e/go.mod h1:EXlVlkqNba9rJe3j7w3Xa924itAMLgZH4UD/Q4PExuQ= -github.com/containerd/continuity v0.1.0/go.mod h1:ICJu0PwR54nI0yPEnJ6jcS+J7CZAUXrLh8lPo2knzsM= -github.com/containerd/continuity v0.2.2/go.mod h1:pWygW9u7LtS1o4N/Tn0FoCFDIXZ7rxcMX7HX1Dmibvk= -github.com/containerd/fifo v0.0.0-20180307165137-3d5202aec260/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/fifo v0.0.0-20190226154929-a9fb20d87448/go.mod h1:ODA38xgv3Kuk8dQz2ZQXpnv/UZZUHUCL7pnLehbXgQI= -github.com/containerd/fifo v0.0.0-20200410184934-f15a3290365b/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= -github.com/containerd/fifo v0.0.0-20201026212402-0724c46b320c/go.mod h1:jPQ2IAeZRCYxpS/Cm1495vGFww6ecHmMk1YJH2Q5ln0= -github.com/containerd/fifo v0.0.0-20210316144830-115abcc95a1d/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= -github.com/containerd/fifo v1.0.0/go.mod h1:ocF/ME1SX5b1AOlWi9r677YJmCPSwwWnQ9O123vzpE4= -github.com/containerd/go-cni v1.0.1/go.mod h1:+vUpYxKvAF72G9i1WoDOiPGRtQpqsNW/ZHtSlv++smU= -github.com/containerd/go-cni v1.0.2/go.mod h1:nrNABBHzu0ZwCug9Ije8hL2xBCYh/pjfMb1aZGrrohk= -github.com/containerd/go-cni v1.1.0/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= -github.com/containerd/go-cni v1.1.3/go.mod h1:Rflh2EJ/++BA2/vY5ao3K6WJRR/bZKsX123aPk+kUtA= -github.com/containerd/go-runc v0.0.0-20180907222934-5a6d9f37cfa3/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/go-runc v0.0.0-20190911050354-e029b79d8cda/go.mod h1:IV7qH3hrUgRmyYrtgEeGWJfWbgcHL9CSRruz2Vqcph0= -github.com/containerd/go-runc v0.0.0-20200220073739-7016d3ce2328/go.mod h1:PpyHrqVs8FTi9vpyHwPwiNEGaACDxT/N/pLcvMSRA9g= -github.com/containerd/go-runc v0.0.0-20201020171139-16b287bc67d0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/go-runc v1.0.0/go.mod h1:cNU0ZbCgCQVZK4lgG3P+9tn9/PaJNmoDXPpoJhDR+Ok= -github.com/containerd/imgcrypt v1.0.1/go.mod h1:mdd8cEPW7TPgNG4FpuP3sGBiQ7Yi/zak9TYCG3juvb0= -github.com/containerd/imgcrypt v1.0.4-0.20210301171431-0ae5c75f59ba/go.mod h1:6TNsg0ctmizkrOgXRNQjAPFWpMYRWuiB6dSF4Pfa5SA= -github.com/containerd/imgcrypt v1.1.1-0.20210312161619-7ed62a527887/go.mod h1:5AZJNI6sLHJljKuI9IHnw1pWqo/F0nGDOuR9zgTs7ow= -github.com/containerd/imgcrypt v1.1.1/go.mod h1:xpLnwiQmEUJPvQoAapeb2SNCxz7Xr6PJrXQb0Dpc4ms= -github.com/containerd/imgcrypt v1.1.3/go.mod h1:/TPA1GIDXMzbj01yd8pIbQiLdQxed5ue1wb8bP7PQu4= -github.com/containerd/nri v0.0.0-20201007170849-eb1350a75164/go.mod h1:+2wGSDGFYfE5+So4M5syatU0N0f0LbWpuqyMi4/BE8c= -github.com/containerd/nri v0.0.0-20210316161719-dbaa18c31c14/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/nri v0.1.0/go.mod h1:lmxnXF6oMkbqs39FiCt1s0R2HSMhcLel9vNL3m4AaeY= -github.com/containerd/stargz-snapshotter/estargz v0.4.1/go.mod h1:x7Q9dg9QYb4+ELgxmo4gBUeJB0tl5dqH1Sdz0nJU1QM= -github.com/containerd/ttrpc v0.0.0-20190828154514-0e0f228740de/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20190828172938-92c8520ef9f8/go.mod h1:PvCDdDGpgqzQIzDW1TphrGLssLDZp2GuS+X5DkEJB8o= -github.com/containerd/ttrpc v0.0.0-20191028202541-4f1b8fe65a5c/go.mod h1:LPm1u0xBw8r8NOKoOdNMeVHSawSsltak+Ihv+etqsE8= -github.com/containerd/ttrpc v1.0.1/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/ttrpc v1.0.2/go.mod h1:UAxOpgT9ziI0gJrmKvgcZivgxOp8iFPSk8httJEt98Y= -github.com/containerd/ttrpc v1.1.0/go.mod h1:XX4ZTnoOId4HklF4edwc4DcqskFZuvXB1Evzy5KFQpQ= -github.com/containerd/typeurl v0.0.0-20180627222232-a93fcdb778cd/go.mod h1:Cm3kwCdlkCfMSHURc+r6fwoGH6/F1hH3S4sg0rLFWPc= -github.com/containerd/typeurl v0.0.0-20190911142611-5eb25027c9fd/go.mod h1:GeKYzf2pQcqv7tJ0AoCuuhtnqhva5LNU3U+OyKxxJpk= -github.com/containerd/typeurl v1.0.1/go.mod h1:TB1hUtrpaiO88KEK56ijojHS1+NeF0izUACaJW2mdXg= -github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s= -github.com/containerd/zfs v0.0.0-20200918131355-0a33824f23a2/go.mod h1:8IgZOBdv8fAgXddBT4dBXJPtxyRsejFIpXoklgxgEjw= -github.com/containerd/zfs v0.0.0-20210301145711-11e8f1707f62/go.mod h1:A9zfAbMlQwE+/is6hi0Xw8ktpL+6glmqZYtevJgaB8Y= -github.com/containerd/zfs v0.0.0-20210315114300-dde8f0fda960/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containerd/zfs v0.0.0-20210324211415-d5c4544f0433/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containerd/zfs v1.0.0/go.mod h1:m+m51S1DvAP6r3FcmYCp54bQ34pyOwTieQDNRIRHsFY= -github.com/containernetworking/cni v0.7.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v0.8.0/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v0.8.1/go.mod h1:LGwApLUm2FpoOfxTDEeq8T9ipbpZ61X79hmU3w8FmsY= -github.com/containernetworking/cni v1.0.1/go.mod h1:AKuhXbN5EzmD4yTNtfSsX3tPcmtrBI6QcRV0NiNt15Y= -github.com/containernetworking/plugins v0.8.6/go.mod h1:qnw5mN19D8fIwkqW7oHHYDHVlzhJpcY6TQxn/fUyDDM= -github.com/containernetworking/plugins v0.9.1/go.mod h1:xP/idU2ldlzN6m4p5LmGiwRDjeJr6FLK6vuiUwoH7P8= -github.com/containernetworking/plugins v1.0.1/go.mod h1:QHCfGpaTwYTbbH+nZXKVTxNBDZcxSOplJT5ico8/FLE= -github.com/containers/ocicrypt v1.0.1/go.mod h1:MeJDzk1RJHv89LjsH0Sp5KTY3ZYkjXO/C+bKAeWFIrc= -github.com/containers/ocicrypt v1.1.0/go.mod h1:b8AOe0YR67uU8OqfVNcznfFpAzu3rdgUV4GP9qXPfu4= -github.com/containers/ocicrypt v1.1.1/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= -github.com/containers/ocicrypt v1.1.2/go.mod h1:Dm55fwWm1YZAjYRaJ94z2mfZikIyIN4B0oB3dj3jFxY= -github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/go-iptables v0.4.5/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-iptables v0.5.0/go.mod h1:/mVI274lEDI2ns62jHCDnCyBF9Iwsmekav8Dbxlm1MU= -github.com/coreos/go-iptables v0.6.0/go.mod h1:Qe8Bv2Xik5FyTXwgIbLAnv2sWSBmvWdFETJConOQ//Q= -github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= -github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= -github.com/coreos/go-systemd v0.0.0-20161114122254-48702e0da86b/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd v0.0.0-20180511133405-39ca1b05acc7/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= -github.com/coreos/go-systemd/v22 v22.0.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= -github.com/coreos/go-systemd/v22 v22.1.0/go.mod h1:xO0FLkIi5MaZafQlIrOotqXZ90ih+1atmu1JpKERPPk= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= -github.com/coreos/pkg v0.0.0-20160727233714-3ac0863d7acf/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= -github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= -github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/cyphar/filepath-securejoin v0.2.2/go.mod h1:FpkQEhXnPnOthhzymB7CGsFk2G9VLXONKD9G7QGMM+4= -github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4= -github.com/d2g/dhcp4 v0.0.0-20170904100407-a1d1b6c41b1c/go.mod h1:Ct2BUK8SB0YC1SMSibvLzxjeJLnrYEVLULFNiHY9YfQ= -github.com/d2g/dhcp4client v1.0.0/go.mod h1:j0hNfjhrt2SxUOw55nL0ATM/z4Yt3t2Kd1mW34z5W5s= -github.com/d2g/dhcp4server v0.0.0-20181031114812-7d4a0a7f59a5/go.mod h1:Eo87+Kg/IX2hfWJfwxMzLyuSZyxSoAug2nGa1G2QAi8= -github.com/d2g/hardwareaddr v0.0.0-20190221164911-e7d9fbe030e4/go.mod h1:bMl4RjIciD2oAxI7DmWRx6gbeqrkoLqv3MV0vzNad+I= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/denisenkom/go-mssqldb v0.12.2/go.mod h1:lnIw1mZukFRZDJYQ0Pb833QS2IaC3l5HkEfra2LJ+sk= -github.com/dennwc/varint v1.0.0/go.mod h1:hnItb35rvZvJrbTALZtY/iQfDs48JKRG1RPpgziApxA= -github.com/denverdino/aliyungo v0.0.0-20190125010748-a747050bb1ba/go.mod h1:dV8lFg6daOBZbT6/BDGIz6Y3WFGn8juu6G+CQ6LHtl0= +github.com/denisenkom/go-mssqldb v0.12.0/go.mod h1:iiK0YP1ZeepvmBQk/QpLEhhTNJgfzrpArPY/aFvc9yU= github.com/devigned/tab v0.1.1/go.mod h1:XG9mPq0dFghrYvoBF3xdRrJzSTX1b7IQrvaL9mzjeJY= -github.com/dgrijalva/jwt-go v0.0.0-20170104182250-a601269ab70c/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= -github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/dgryski/go-sip13 v0.0.0-20200911182023-62edffca9245/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= -github.com/digitalocean/godo v1.78.0/go.mod h1:GBmu8MkjZmNARE7IXRPmkbbnocNN8+uBm0xbEVw2LCs= -github.com/digitalocean/godo v1.81.0/go.mod h1:BPCqvwbjbGqxuUnIKB4EvS/AX7IDnNmt5fwvIkWo+ew= +github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8= github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/j0mACtrfE= -github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E= -github.com/dnaeon/go-vcr v1.1.0/go.mod h1:M7tiix8f0r6mKKJ3Yq/kqU1OYf3MnfmBWVbPx/yU9ko= github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ= -github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= -github.com/docker/distribution v0.0.0-20190905152932-14b96e55d84c/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY= -github.com/docker/distribution v2.7.1-0.20190205005809-0d3efadf0154+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w= -github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.14+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker v20.10.17+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= -github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y= -github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec= -github.com/docker/go-events v0.0.0-20170721190031-9461782956ad/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA= -github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI= -github.com/docker/go-metrics v0.0.1/go.mod h1:cG1hvH2utMXtqgqqYE9plW6lDxS3/5ayHzueweSI3Vw= -github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= -github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE= -github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= -github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= -github.com/dustin/go-humanize v0.0.0-20171111073723-bb3d318650d4/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= -github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs= -github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= -github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= -github.com/edsrzf/mmap-go v1.1.0/go.mod h1:19H/e8pUPLicwkyNgOykDXkJ9F0MHE+Z52B8EIth78Q= -github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= -github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= -github.com/envoyproxy/go-control-plane v0.6.9/go.mod h1:SBwIajubJHhxtWwsL9s8ss4safvEdbitLhGGK48rN6g= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -504,166 +232,45 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m github.com/envoyproxy/go-control-plane v0.9.9-0.20210217033140-668b12f5399d/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ= github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0= -github.com/envoyproxy/go-control-plane v0.10.1/go.mod h1:AY7fTTXNdv/aJ2O5jwpxAPOWUZ7hQAEvzN5Pf27BkQQ= -github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= -github.com/envoyproxy/go-control-plane v0.10.3/go.mod h1:fJJn/j26vwOu972OllsvAgJJM//w9BV6Fxbg2LuVd34= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/envoyproxy/protoc-gen-validate v0.6.7/go.mod h1:dyJXwwfPK2VSqiB9Klm1J6romD608Ba7Hij42vrOBCo= -github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.11.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= -github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k= github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g= -github.com/franela/goblin v0.0.0-20200105215937-c9ffbefa60db/go.mod h1:7dvUGVsVBjqR7JHJk0brhHOZYGmfBYOrK0ZhYMEtBr4= -github.com/franela/goreq v0.0.0-20171204163338-bcd34c9993f8/go.mod h1:ZhphrRTfi2rbfLwlschooIH4+wKKDR4Pdxhh+TRoA20= -github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= -github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= -github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= -github.com/fsnotify/fsnotify v1.5.4/go.mod h1:OVB6XrOHzAwXMpEM7uPOzcehqUV2UqJxmVXmkdnm1bU= -github.com/fullsailor/pkcs7 v0.0.0-20190404230743-d7302db945fa/go.mod h1:KnogPXtdwXqoenmZCw6S+25EAm2MkxbG0deNDu4cbSA= -github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= -github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= -github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= -github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M= -github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U= +github.com/gin-gonic/gin v1.7.3/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= -github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= -github.com/go-kit/kit v0.10.0/go.mod h1:xUsJbQ/Fp4kEt7AFgCuvyX4a71u8h9jB8tj/ORgOZ7o= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= -github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= -github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= -github.com/go-logr/logr v0.4.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= github.com/go-logr/logr v1.0.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.1/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/stdr v1.2.0/go.mod h1:YkVgnZu1ZjjL7xTxrfm/LLZBfkhTqSR1ydtm6jTKKwI= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A= github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4= -github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= -github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= -github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc= -github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= -github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/runtime v0.23.1/go.mod h1:AKurw9fNre+h3ELZfk6ILsfvPN+bvvlaU/M9q/r9hpk= -github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= -github.com/go-openapi/spec v0.19.3/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.2/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= -github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8= github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA= github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI= github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4= -github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= -github.com/go-zookeeper/zk v1.0.2/go.mod h1:nOB03cncLtlp4t+UAkGSV+9beXP/akpekBwL+UX1Qcw= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= -github.com/goccy/go-yaml v1.9.5/go.mod h1:U/jl18uSupI5rdI2jmuCswEA2htH9eXfferR3KfscvA= -github.com/godbus/dbus v0.0.0-20151105175453-c7fdd8b5cd55/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20180201030542-885f9cc04c9c/go.mod h1:/YcGZj5zSblfDWMMoOzV4fas9FZnQYTkDnsGvmh2Grw= -github.com/godbus/dbus v0.0.0-20190422162347-ade71ed3457e/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= -github.com/godbus/dbus/v5 v5.0.3/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= -github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= -github.com/gogo/googleapis v1.1.0/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= -github.com/gogo/googleapis v1.2.0/go.mod h1:Njal3psf3qN6dwBtQfUmBZh2ybovJ0tlu3o/AC7HYjU= -github.com/gogo/googleapis v1.4.0/go.mod h1:5YRNX2z1oM5gXdAkurHa942MDgEJyk02w4OecKY87+c= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= -github.com/gogo/protobuf v1.2.2-0.20190723190241-65acae22fc9d/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.0/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= -github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= -github.com/golang-jwt/jwt/v4 v4.2.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg= github.com/golang-jwt/jwt/v4 v4.4.1/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v4 v4.4.2 h1:rcc4lwaZgFMCZ5jxF9ABolDcIHdBytAFgqFPbSJQAYs= github.com/golang-jwt/jwt/v4 v4.4.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= -github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188/go.mod h1:vXjM/+wXQnTPR4KqTKDgJukSZ6amVRtWMPEjE6sQoK8= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= -github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -696,14 +303,9 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= -github.com/google/gnostic v0.5.7-v3refs/go.mod h1:73MKFl6jIHelAJNaBGFzt3SPtZULs9dYrGFt8OiIsHQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -720,7 +322,6 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8 github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/go-containerregistry v0.5.1/go.mod h1:Ct15B4yir3PLOP5jsy0GNeYVaIZs/MK/Jz5any1wFW0= github.com/google/go-github/v38 v38.1.0 h1:C6h1FkaITcBFK7gAmq4eFzt6gbhEhk7L5z6R3Uva+po= github.com/google/go-github/v38 v38.1.0/go.mod h1:cStvrz/7nFr0FoENgG6GLbp53WaelXucT+BBz/3VKx4= github.com/google/go-github/v45 v45.2.0 h1:5oRLszbrkvxDDqBCNj2hjDZMKmvexaZ1xw/FCD+K3FI= @@ -735,8 +336,6 @@ github.com/google/go-replayers/grpcreplay v1.1.0/go.mod h1:qzAvJ8/wi57zq7gWqaE6A github.com/google/go-replayers/httpreplay v1.1.1 h1:H91sIMlt1NZzN7R+/ASswyouLJfW0WLW7fhyUFvDEkY= github.com/google/go-replayers/httpreplay v1.1.1/go.mod h1:gN9GeLIs7l6NUoVaSSnv2RiqK1NiwAmD0MrKeC9IIks= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:xmapqc1AyLoB+ddYT6r04bD9lIjlOqGaREovi0SzFaE= github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= @@ -760,20 +359,14 @@ github.com/google/pprof v0.0.0-20210506205249-923b5ab0fc1a/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= -github.com/google/pprof v0.0.0-20220318212150-b2ab0324ddda/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg= -github.com/google/pprof v0.0.0-20220608213341-c488b8fa1db3/go.mod h1:gSuNB+gJaOiQKLEZ+q+PK9Mq3SOzhRcw2GsGS/FhYDk= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= -github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/wire v0.5.0 h1:I7ELFeVBr3yfPIcc8+MWvrjk+3VjbcSzoXm3JVa+jD8= github.com/google/wire v0.5.0/go.mod h1:ngWDr9Qvq3yZA10YrxfyGELY/AFWGVpy9c1LTRi1EoU= -github.com/googleapis/enterprise-certificate-proxy v0.0.0-20220520183353-fd19c99a87aa/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= -github.com/googleapis/enterprise-certificate-proxy v0.1.0/go.mod h1:17drOmN3MwGY7t0e+Ei9b45FFGA3fBs3x36SsCg1hq8= github.com/googleapis/enterprise-certificate-proxy v0.2.0 h1:y8Yozv7SZtlU//QXbezB6QkpuE6jMD2/gfzk4AftXjs= github.com/googleapis/enterprise-certificate-proxy v0.2.0/go.mod h1:8C0jb7/mgJe/9KK8Lm7X9ctZC2t60YyIpYEI16jx0Qg= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= @@ -781,109 +374,18 @@ github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5m github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= -github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= -github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= github.com/googleapis/gax-go/v2 v2.6.0 h1:SXk3ABtQYDT/OH8jAyvEOQ58mgawq5C4o/4/89qN2ZU= github.com/googleapis/gax-go/v2 v2.6.0/go.mod h1:1mjbznJAPHFpesgE5ucqfYEscaz5kMdcIDwU/6+DDoY= -github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= -github.com/googleapis/gnostic v0.5.1/go.mod h1:6U4PtQXGIEt/Z3h5MAT7FNofLnw9vXk2cUuW7uA/OeU= -github.com/googleapis/gnostic v0.5.5/go.mod h1:7+EbHbldMins07ALC74bsA81Ovc97DwqyJO1AENw9kA= -github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= -github.com/gophercloud/gophercloud v0.24.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= -github.com/gophercloud/gophercloud v0.25.0/go.mod h1:Q8fZtyi5zZxPS/j9aj3sSxtvj41AdQMDwyo1myduD5c= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= -github.com/gorilla/handlers v0.0.0-20150720190736-60c7bfde3e33/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ= -github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/gorilla/websocket v0.0.0-20170926233335-4201258b820c/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= -github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/gorilla/websocket v1.4.1/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= -github.com/grafana/regexp v0.0.0-20220304095617-2e8d9baf4ac2/go.mod h1:M5qHK+eWfAv8VR/265dIuEpL3fNfeC21tXXp9itM24A= -github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.0.1-0.20190118093823-f849b5445de4/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= -github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= -github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= -github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= -github.com/grpc-ecosystem/grpc-gateway v1.9.5/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0/go.mod h1:hgWBS7lorOAVIJEQMi4ZsPv9hVvWI6+ch50m39Pf2Ks= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.10.2/go.mod h1:chrfS3YoLAlKTRE5cFWvCbt8uGAjshktT4PveTUpsFQ= github.com/hanwen/go-fuse v1.0.0/go.mod h1:unqXarDXqzAk0rt98O2tVndEPIpUgLD9+rwFisZH3Ok= github.com/hanwen/go-fuse/v2 v2.1.0/go.mod h1:oRyA5eK+pvJyv5otpO/DgccS8y/RvYMaO00GgRLGryc= -github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q= -github.com/hashicorp/consul/api v1.3.0/go.mod h1:MmDNSzIMUjNpY/mQ398R4bk2FnqQLoPndWW5VkKPlCE= -github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0= -github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ= -github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.3.0/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= -github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms= -github.com/hashicorp/cronexpr v1.1.1/go.mod h1:P4wA0KBl9C5q2hABiMO7cp6jcIg96CDh1Efb3g1PWA4= -github.com/hashicorp/errwrap v0.0.0-20141028054710-7554cd9344ce/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.12.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-hclog v0.12.2/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= -github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-immutable-radix v1.2.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= -github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= -github.com/hashicorp/go-multierror v0.0.0-20161216184304-ed905158d874/go.mod h1:JMRHfdO9jKNzS/+BTlxCjKNQHg/jZAft8U7LloJvN7I= -github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= -github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+vmowP0z+KUhOZdA= -github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.7.1/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY= -github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= -github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= -github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= -github.com/hashicorp/go-sockaddr v1.0.2/go.mod h1:rB4wwRAUzs07qva3c5SdrY/NEtAUjGlgmH/UkBUC97A= -github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= -github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ= -github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= -github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I= -github.com/hashicorp/memberlist v0.3.0/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/memberlist v0.3.1/go.mod h1:MS2lj3INKhZjWNqd3N0m3J+Jxf3DAOnAH9VT3Sh9MUE= -github.com/hashicorp/nomad/api v0.0.0-20220629141207-c2428e1673ec/go.mod h1:jP79oXjopTyH6E8LF0CEMq67STgrlmBRIyijA0tuR5o= -github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= -github.com/hashicorp/serf v0.9.6/go.mod h1:TXZNMjZQijwlDvp+r0b63xZ45H7JmCmgg4gpTwn9UV4= -github.com/hetznercloud/hcloud-go v1.33.1/go.mod h1:XX/TQub3ge0yWR2yHWmnDVIrB+MQbda1pHxkUmDlUME= -github.com/hetznercloud/hcloud-go v1.35.0/go.mod h1:mepQwR6va27S3UQthaEPGS86jtzSY9xWL1e9dyxXpgA= -github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/hudl/fargo v1.3.0/go.mod h1:y3CKSmjA+wD2gak7sUSXTAoopbhU08POFhmITJgmKTg= github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0= github.com/iancoleman/strcase v0.2.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -github.com/ianlancetaylor/demangle v0.0.0-20220319035150-800ac71e25c2/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w= -github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= -github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo= -github.com/intel/goresctrl v0.2.0/go.mod h1:+CZdzouYFn5EsxgqAQTEzMfwKwuc0fVdMrT9FCCAVRQ= -github.com/ionos-cloud/sdk-go/v6 v6.1.0/go.mod h1:Ox3W0iiEz0GHnfY9e5LmAxwklsxguuNFEUSu0gVRTME= -github.com/j-keck/arping v0.0.0-20160618110441-2cf9dc699c56/go.mod h1:ymszkNOg6tORTn+6F6j+Jc8TOr5osrynvN6ivFWZ2GA= -github.com/j-keck/arping v1.0.2/go.mod h1:aJbELhR92bSk7tp79AWM/ftfc90EfEi2bQJrbBFOsPw= github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo= github.com/jackc/chunkreader/v2 v2.0.0/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= github.com/jackc/chunkreader/v2 v2.0.1/go.mod h1:odVSm741yZoC3dpHEUXIqA9tQRhFrgOHwnPIn9lDKlk= @@ -893,7 +395,7 @@ github.com/jackc/pgconn v0.0.0-20190831204454-2fabfa3c18b7/go.mod h1:ZJKsE/KZfsU github.com/jackc/pgconn v1.8.0/go.mod h1:1C2Pb36bGIP9QHGBYCjnyhqu7Rv3sGshaQUvmfGIB/o= github.com/jackc/pgconn v1.9.0/go.mod h1:YctiPyvzfU11JFxoXokUOOKQXQmDMoJL9vJzHH8/2JY= github.com/jackc/pgconn v1.9.1-0.20210724152538-d89c8390a530/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= -github.com/jackc/pgconn v1.12.1/go.mod h1:ZkhRC59Llhrq3oSfrikvwQ5NaxYExr6twkdkMLaKono= +github.com/jackc/pgconn v1.11.0/go.mod h1:4z2w8XhRbP1hYxkpTuBjTS3ne3J48K83+u0zoyvg2pI= github.com/jackc/pgio v1.0.0/go.mod h1:oP+2QK2wFfUWgr+gxjoBH9KGBb31Eio69xUb0w5bYf8= github.com/jackc/pgmock v0.0.0-20190831213851-13a1b77aafa2/go.mod h1:fGZlG77KXmcq05nJLRkk0+p82V8B8Dw8KN2/V9c/OAE= github.com/jackc/pgmock v0.0.0-20201204152224-4fe30f7445fd/go.mod h1:hrBW0Enj2AZTNpt/7Y5rr2xe/9Mn757Wtb2xeBzPv2c= @@ -906,503 +408,122 @@ github.com/jackc/pgproto3/v2 v2.0.0-rc3/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvW github.com/jackc/pgproto3/v2 v2.0.0-rc3.0.20190831210041-4c03ce451f29/go.mod h1:ryONWYqW6dqSg1Lw6vXNMXoBJhpzvWKnT95C46ckYeM= github.com/jackc/pgproto3/v2 v2.0.6/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgproto3/v2 v2.1.1/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= -github.com/jackc/pgproto3/v2 v2.3.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= +github.com/jackc/pgproto3/v2 v2.2.0/go.mod h1:WfJCnwN3HIg9Ish/j3sgWXnAfK8A9Y0bwXYU5xKaEdA= github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b/go.mod h1:vsD4gTJCa9TptPL8sPkXrLZ+hDuNrZCnj29CQpr4X1E= github.com/jackc/pgtype v0.0.0-20190421001408-4ed0de4755e0/go.mod h1:hdSHsc1V01CGwFsrv11mJRHWJ6aifDLfdV3aVjFF0zg= github.com/jackc/pgtype v0.0.0-20190824184912-ab885b375b90/go.mod h1:KcahbBH1nCMSo2DXpzsoWOAfFkdEtEJpPbVLq8eE+mc= github.com/jackc/pgtype v0.0.0-20190828014616-a8802b16cc59/go.mod h1:MWlu30kVJrUS8lot6TQqcg7mtthZ9T0EoIBFiJcmcyw= github.com/jackc/pgtype v1.8.1-0.20210724151600-32e20a603178/go.mod h1:C516IlIV9NKqfsMCXTdChteoXmwgUceqaLfjg2e3NlM= -github.com/jackc/pgtype v1.11.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= +github.com/jackc/pgtype v1.10.0/go.mod h1:LUMuVrfsFfdKGLw+AFFVv6KtHOFMwRgDDzBt76IqCA4= github.com/jackc/pgx/v4 v4.0.0-20190420224344-cc3461e65d96/go.mod h1:mdxmSJJuR08CZQyj1PVQBHy9XOp5p8/SHH6a0psbY9Y= github.com/jackc/pgx/v4 v4.0.0-20190421002000-1b8f0016e912/go.mod h1:no/Y67Jkk/9WuGR0JG/JseM9irFbnEPbuWV2EELPNuM= github.com/jackc/pgx/v4 v4.0.0-pre1.0.20190824185557-6972a5742186/go.mod h1:X+GQnOEnf1dqHGpw7JmHqHc1NxDoalibchSk9/RWuDc= github.com/jackc/pgx/v4 v4.12.1-0.20210724153913-640aa07df17c/go.mod h1:1QD0+tgSXP7iUjYm9C1NxKhny7lq6ee99u/z+IHFcgs= -github.com/jackc/pgx/v4 v4.16.1/go.mod h1:SIhx0D5hoADaiXZVyv+3gSm3LCIIINTVO0PficsvWGQ= +github.com/jackc/pgx/v4 v4.15.0/go.mod h1:D/zyOyXiaM1TmVWnOM18p0xdDtdakRBa0RsVGI3U3bw= github.com/jackc/puddle v0.0.0-20190413234325-e4ced69a3a2b/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v0.0.0-20190608224051-11cab39313c9/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.1.3/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= github.com/jackc/puddle v1.2.1/go.mod h1:m4B5Dj62Y0fbyuIc15OsIqK0+JU8nkqQjsgx7dvjSWk= -github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20160803190731-bd40a432e4c7/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= -github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= -github.com/joefitzgerald/rainbow-reporter v0.1.0/go.mod h1:481CNgqmVHQZzdIbN52CupLJyoVwB10FQ/IQlF1pdL8= github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= -github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jszwec/csvutil v1.7.1 h1:btxPxFwms8lHMgl0OIgOQ4Tayfqo0xid0hGkq1kM510= github.com/jszwec/csvutil v1.7.1/go.mod h1:Rpu7Uu9giO9subDyMCIQfHVDuLrcaC36UA4YcJjGBkg= -github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= -github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= -github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.10.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.3/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.11.13/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= github.com/klauspost/compress v1.15.1/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/kolo/xmlrpc v0.0.0-20201022064351-38db28db192b/go.mod h1:pcaDhQK0/NJZEvtCO0qQPPropqV0sJOJ6YW7X+9kRwM= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= -github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA= github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= -github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.1.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= -github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM= -github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4= -github.com/linode/linodego v1.4.0/go.mod h1:PVsRxSlOiJyvG4/scTszpmZDTdgS+to3X6eS8pRrWI8= -github.com/linode/linodego v1.8.0/go.mod h1:heqhl91D8QTPVm2k9qZHP78zzbOdTFLXE9NJc3bcc50= -github.com/linuxkit/virtsock v0.0.0-20201010232012-f8cee7dfc7a3/go.mod h1:3r6x7q95whyfWQpmGZTu3gk3v2YkMi05HEzl7Tf7YEo= -github.com/lyft/protoc-gen-star v0.6.0/go.mod h1:TGAoBVkt8w7MPG72TrKIu85MIdXwDuzJYeZuUPFPNwA= -github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= -github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= -github.com/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= -github.com/marstr/guid v1.1.0/go.mod h1:74gB1z2wpxxInTG6yaqA7KrtM0NZ+RbrcqDvYHefzho= -github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/lib/pq v1.10.4/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= -github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= -github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= -github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI= +github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= -github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= -github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= -github.com/mattn/go-shellwords v1.0.3/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.6/go.mod h1:3xCvwCdWdlDJUrvuMn7Wuy9eWs4pE8vqg+NOMyg4B2o= -github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= -github.com/maxbrunsfeld/counterfeiter/v6 v6.2.2/go.mod h1:eD9eIE7cdwcMi9rYluz88Jz2VyhSmden33/aXg4oVIY= -github.com/microsoft/ApplicationInsights-Go v0.4.4/go.mod h1:fKRUseBqkw6bDiXTs3ESTiU/4YTIHsQS4W3fP2ieF4U= -github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= -github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= -github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= -github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs= -github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4= -github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= -github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= -github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= -github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= -github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= -github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= -github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= -github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= -github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.4.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= -github.com/moby/locker v1.0.1/go.mod h1:S7SDdo5zpBK84bzzVlKr2V0hz+7x9hWbYC/kq7oQppc= -github.com/moby/spdystream v0.2.0/go.mod h1:f7i0iNDQJ059oMTcWxx8MA/zKFIuD/lY+0GqbN2Wy8c= -github.com/moby/sys/mountinfo v0.4.0/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.4.1/go.mod h1:rEr8tzG/lsIZHBtN/JjGG+LMYx9eXgW2JI+6q0qou+A= -github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU= -github.com/moby/sys/signal v0.6.0/go.mod h1:GQ6ObYZfqacOwTtlXvcmh9A26dVRul/hbOZn88Kg8Tg= -github.com/moby/sys/symlink v0.1.0/go.mod h1:GGDODQmbFOjFsXvfLVn3+ZRxkch54RkSiGqsZeMYowQ= -github.com/moby/sys/symlink v0.2.0/go.mod h1:7uZVF2dqJjG/NsClqul95CqKOBRQyYSNnJ6BMgR/gFs= -github.com/moby/term v0.0.0-20200312100748-672ec06f55cd/go.mod h1:DdlQx2hp0Ss5/fLikoLlEeIYiATotOjgB//nb973jeo= -github.com/moby/term v0.0.0-20210610120745-9d4ed1856297/go.mod h1:vgPCkQMyxTZ7IDy8SXRufE172gr8+K/JE/7hHFxHW3A= -github.com/moby/term v0.0.0-20210619224110-3f7ff695adc6/go.mod h1:E2VnQOmVuvZB6UYnnDB0qG5Nq/1tD9acaOpo6xmt0Kw= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= -github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= -github.com/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ= -github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= -github.com/nats-io/jwt v0.3.0/go.mod h1:fRYCDE99xlTsqUzISS1Bi75UBJ6ljOJQOAAu5VglpSg= -github.com/nats-io/jwt v0.3.2/go.mod h1:/euKqTS1ZD+zzjYrY7pseZrTtWQSjujC7xjPc8wL6eU= -github.com/nats-io/nats-server/v2 v2.1.2/go.mod h1:Afk+wRZqkMQs/p45uXdrVLuab3gwv3Z8C4HTBu8GD/k= -github.com/nats-io/nats.go v1.9.1/go.mod h1:ZjDU1L/7fJ09jvUSRVBR2e7+RnLiiIQyqyzEE/Zbp4w= -github.com/nats-io/nkeys v0.1.0/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nkeys v0.1.3/go.mod h1:xpnFELMwJABBLVhffcfd1MZx6VsNRFpEugbxziKVo7w= -github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= -github.com/ncw/swift v1.0.47/go.mod h1:23YIA4yWVnGwv2dQlN4bB7egfYX6YLn0Yo/S6zZO/ZM= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= -github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= -github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= -github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/olekukonko/tablewriter v0.0.0-20170122224234-a0225b3f23b5/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= -github.com/onsi/ginkgo v0.0.0-20151202141238-7f8ab55aaf3b/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.10.3/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= -github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= -github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= -github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= -github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= -github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= -github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= -github.com/onsi/ginkgo/v2 v2.4.0 h1:+Ig9nvqgS5OBSACXNk15PLdp0U9XPYROt9CFzVdFGIs= -github.com/onsi/gomega v0.0.0-20151007035656-2152b45fa28a/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= -github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= -github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= -github.com/onsi/gomega v1.9.0/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA= -github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= -github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= -github.com/onsi/gomega v1.15.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= +github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= -github.com/opencontainers/go-digest v0.0.0-20170106003457-a6d0ee40d420/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v0.0.0-20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0-rc1.0.20180430190053-c9281466c8b2/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s= -github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= -github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2-0.20211117181255-693428a734f5/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0= -github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc8.0.20190926000215-3e425f80a8c9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc9/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U= -github.com/opencontainers/runc v1.0.0-rc93/go.mod h1:3NOsor4w32B2tC0Zbl8Knk4Wg84SM2ImC1fxBuqJ/H0= -github.com/opencontainers/runc v1.0.2/go.mod h1:aTaHFFwQXuA71CiyxOdFFIorAoemI04suvGRQFzWTD0= -github.com/opencontainers/runc v1.1.0/go.mod h1:Tj1hFw6eFWp/o33uxGf5yF2BX5yz2Z6iptFpuvbbKqc= -github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.1/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.2-0.20190207185410-29686dbc5559/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.2/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20200929063507-e6143ca7d51d/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0= -github.com/opencontainers/runtime-tools v0.0.0-20181011054405-1d69bd0f9c39/go.mod h1:r3f7wjNzSs2extwzU3Y+6pKfobzPh+kKFJ3ofN+3nfs= -github.com/opencontainers/selinux v1.6.0/go.mod h1:VVGKuOLlE7v4PJyT6h7mNWvq1rzqiriPsEqVhc+svHE= -github.com/opencontainers/selinux v1.8.0/go.mod h1:RScLhm78qiWa2gbVCcGkC7tCGdgk3ogry1nUQF8Evvo= -github.com/opencontainers/selinux v1.8.2/go.mod h1:MUIHuUEvKB1wtJjQdOyYRgOnLD2xAPP8dBsCoU0KuF8= -github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI= -github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= -github.com/opentracing/basictracer-go v1.0.0/go.mod h1:QfBfYuafItcjQuMwinw9GhYKwFXS9KnPs5lxoYwgW74= -github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/openzipkin-contrib/zipkin-go-opentracing v0.4.5/go.mod h1:/wsWhb9smxSfWAKL3wpBW7V8scJMt8N8gnaMCS9E/cA= -github.com/openzipkin/zipkin-go v0.1.6/go.mod h1:QgAqvLzwWbR/WpD4A3cGpPtJrZXNIiJc5AZX7/PBEpw= -github.com/openzipkin/zipkin-go v0.2.1/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa h1:+JsZaqE07NHU7nnXlNxiODY1W1Z/uY+THUww4QAzzW0= -github.com/ossf/scorecard/v4 v4.8.1-0.20221103134647-6a00f92156aa/go.mod h1:/6X5Q0wvCvWx/K1nyPWXzL2ZG3ZESBhP6okDFyXzcT0= -github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM= -github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= -github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= -github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc= -github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= -github.com/performancecopilot/speed v3.0.0+incompatible/go.mod h1:/CLtqpZ5gBg1M9iaPbIdPPGyKcA8hKdoy6hAWba7Yac= -github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= -github.com/pierrec/lz4 v1.0.2-0.20190131084431-473cd7ce01a1/go.mod h1:3/3N9NVKO0jef7pBehbT1qWhCMrIgbYNnFAZCqQ5LRc= -github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= +github.com/ossf/scorecard/v4 v4.8.1-0.20221113231904-ca55bd0e67ea h1:pX4GJ+yJhaiOdXf+JRaC8C4sIDR1xJxvfvu8bBddjzM= +github.com/ossf/scorecard/v4 v4.8.1-0.20221113231904-ca55bd0e67ea/go.mod h1:yz0RqjuKHzH6wxwRGzaolnimIFAk/38qVgLg2l7kdig= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= -github.com/pkg/browser v0.0.0-20210115035449-ce105d075bb4/go.mod h1:N6UoU20jOqggOuDwUaBQpluzLNDqif3kq9z2wpdYEfQ= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1-0.20171018195549-f15c970de5b7/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= -github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= -github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= -github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= -github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= -github.com/prometheus/alertmanager v0.24.0/go.mod h1:r6fy/D7FRuZh5YbnX6J3MBY0eI4Pb5yPYS7/bPSXXqI= -github.com/prometheus/client_golang v0.0.0-20180209125602-c332b6f63c06/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= -github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs= -github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= -github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= -github.com/prometheus/client_golang v1.1.0/go.mod h1:I1FGZT9+L76gKKOs5djB6ezCbFQP1xR9D75/vuwEF3g= -github.com/prometheus/client_golang v1.3.0/go.mod h1:hJaj2vgQTGQmVCsAACORcieXFeDPbaTKGT+JTgUa3og= -github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= -github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_model v0.0.0-20171117100541-99fa1f4be8e5/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= -github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.1.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.0.0-20180110214958-89604d197083/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= -github.com/prometheus/common v0.2.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.6.0/go.mod h1:eBmuwkDJBwy6iBfxCBob6t6dR6ENT/y+J+Zk0j9GMYc= -github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= -github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.30.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.34.0/go.mod h1:gB3sOl7P0TvJabZpLY5uQMpUqRCPPCyRLCZYc7JZTNE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common/assets v0.1.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= -github.com/prometheus/common/assets v0.2.0/go.mod h1:D17UVUE12bHbim7HzwUvtqm6gwBEaDQ0F+hIGbFbccI= -github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= -github.com/prometheus/exporter-toolkit v0.7.1/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= -github.com/prometheus/procfs v0.0.0-20180125133057-cb4147076ac7/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= -github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.0-20190522114515-bc1a522cf7b1/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= -github.com/prometheus/procfs v0.0.3/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= -github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= -github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.2.0/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/prometheus v0.35.0/go.mod h1:7HaLx5kEPKJ0GDgbODG0fZgXbQ8K/XjZNJXQmbmgQlY= -github.com/prometheus/prometheus v0.37.0/go.mod h1:egARUgz+K93zwqsVIAneFlLZefyGOON44WyAp4Xqbbk= -github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= -github.com/rakyll/embedmd v0.0.0-20171029212350-c8060a0752a2/go.mod h1:7jOTMgqac46PZcF54q6l2hkLEG8op93fZu61KmxWDV4= -github.com/rcrowley/go-metrics v0.0.0-20181016184325-3113b8401b8a/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4= -github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= +github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= +github.com/prometheus/prometheus v2.5.0+incompatible/go.mod h1:oAIUtOny2rjMX0OWN5vPR5/q/twIROJvdqnQKDdil/s= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.8.1 h1:geMPLpDpQOgVyCg5z5GoRwLHepNdb71NXb67XFkP+Eg= github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o= -github.com/rs/cors v1.8.2/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ= github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU= github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc= -github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= -github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= -github.com/safchain/ethtool v0.0.0-20210803160452-9aa261dae9b1/go.mod h1:Z0q5wiBQGYcxhMZ6gUqHn6pYNLypFAvaL3UvgZLR0U4= -github.com/samuel/go-zookeeper v0.0.0-20190923202752-2cc03de413da/go.mod h1:gi+0XIa01GRL2eRQVjQkKGqKF3SF9vZR/HnPullcV2E= github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0= -github.com/scaleway/scaleway-sdk-go v1.0.0-beta.9/go.mod h1:fCa7OJZ/9DRTnOKmxvT6pn+LPWUptQAmHF/SBJUGEcg= -github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= -github.com/sclevine/spec v1.2.0/go.mod h1:W4J29eT/Kzv7/b9IWLB055Z+qvVC9vt0Arko24q7p+U= -github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= -github.com/seccomp/libseccomp-golang v0.9.1/go.mod h1:GbW5+tmTXfcxTToHLXlScSlAvWlF4P2Ca7zGrPiEpWo= -github.com/seccomp/libseccomp-golang v0.9.2-0.20210429002308-3879420cc921/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg= github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 h1:82EIpiGB79OIPgSGa63Oj4Ipf+YAX1c6A9qjmEYoRXc= github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2/go.mod h1:hAF0iLZy4td2EX+/8Tw+4nodhlMrwN3HupfaXj3zkGo= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a h1:KikTa6HtAK8cS1qjvUvvq4QO21QnwC+EfvB+OAuZ/ZU= github.com/shurcooL/graphql v0.0.0-20200928012149-18c5c3165e3a/go.mod h1:AuYgA5Kyo4c7HfUmvRGs/6rGlMMV/6B1bVnB9JxJEEg= -github.com/shurcooL/httpfs v0.0.0-20190707220628-8d4bc4ba7749/go.mod h1:ZY1cvUeJuFPAdZ/B6v7RHavJWZn2YPVFQ1OSXhCGOkg= -github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= -github.com/shurcooL/vfsgen v0.0.0-20200824052919-0d455de96546/go.mod h1:TrYk7fJVaAttu97ZZKrO9UbRa8izdowaMIZcxYMbVaw= -github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc= -github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= -github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= -github.com/sony/gobreaker v0.4.1/go.mod h1:ZKptC7FHNvhBz7dN2LGjPVBz2sZJmc0/PkyDJOjmxWY= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= -github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= -github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY520V4= -github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= -github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= -github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= -github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= -github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= -github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.1/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= -github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= -github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= -github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= -github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= -github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= -github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= -github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI= -github.com/stretchr/objx v0.0.0-20180129172003-8a3f7159479f/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v0.0.0-20180303142811-b89eecf5ca5d/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.5/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20180916011248-d98352740cb2/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= -github.com/tchap/go-patricia v2.2.6+incompatible/go.mod h1:bmLyhP68RS6kStMGxByiQ23RP/odRBOTVjwp2cDyi6I= -github.com/tedsuo/ifrit v0.0.0-20180802180643-bea94bb476cc/go.mod h1:eyZnKCc955uh98WQvzOm0dgAeLnf2O0Rz0LPoC5ze+0= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= -github.com/tmc/grpc-websocket-proxy v0.0.0-20170815181823-89b8d40f7ca8/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= -github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= -github.com/tv42/httpunix v0.0.0-20191220191345-2ba4b9c3382c/go.mod h1:hzIxponao9Kjc7aWznkXaL4U4TWaDSs8zcsY4Ka08nM= -github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= -github.com/urfave/cli v0.0.0-20171014202726-7bc6a0acffa5/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= -github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/urfave/cli v1.22.2/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0= -github.com/vishvananda/netlink v0.0.0-20181108222139-023a6dafdcdf/go.mod h1:+SR5DhBJrl6ZM7CoCKvpw5BKroDKQ+PJqOg65H/2ktk= -github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE= -github.com/vishvananda/netlink v1.1.1-0.20201029203352-d40f9887b852/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= -github.com/vishvananda/netlink v1.1.1-0.20210330154013-f5de75959ad5/go.mod h1:twkDnbuQxJYemMlGd4JFIcuhgX83tXhKS2B/PRMpOho= -github.com/vishvananda/netns v0.0.0-20180720170159-13995c7128cc/go.mod h1:ZjcWmFBXmLKZu9Nxj3WKYEafiSqer2rnvPr0en9UNpI= -github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= -github.com/vishvananda/netns v0.0.0-20200728191858-db3c7e526aae/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/vultr/govultr/v2 v2.17.2/go.mod h1:ZFOKGWmgjytfyjeyAdhQlSWwTjh2ig+X49cAp50dzXI= -github.com/willf/bitset v1.1.11-0.20200630133818-d5bec3311243/go.mod h1:RjeCKbqT1RxIR/KWY6phxZiaY1IyutSBfGjNPySAYV4= -github.com/willf/bitset v1.1.11/go.mod h1:83CECat5yLh5zVOf4P1ErAgKA5UDvKtgyUABdr3+MjI= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= -github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= -github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f/go.mod h1:5yf86TLmAcydyeJq5YvxkGPE2fm/u4myDekKRoLuqhs= -github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= -github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0= -github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= -github.com/yvasiyarov/go-metrics v0.0.0-20140926110328-57bccd1ccd43/go.mod h1:aX5oPXxHm3bOH+xeAttToC8pqch2ScQN/JoXYupl6xs= -github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50/go.mod h1:NUSPSUX/bi6SeDMUh6brw0nXpxHnc96TguQh0+r/ssA= -github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f/go.mod h1:GlGEuHIJweS1mbCqG+7vt2nvWLzLLnRHbXz5JKd/Qbg= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= -go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.3/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= -go.etcd.io/bbolt v1.3.5/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.etcd.io/etcd v0.0.0-20191023171146-3cf2f69b5738/go.mod h1:dnLIgRNXwCJa5e+c6mIZCrds/GIG4ncV9HhK5PX7jPg= -go.etcd.io/etcd v0.5.0-alpha.5.0.20200910180754-dd1b699fc489/go.mod h1:yVHk9ub3CSBatqGNg7GRmsnfLWtoW60w4eDYfh7vHDg= -go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= -go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= -go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= -go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= -go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= -go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= -go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.8.3/go.mod h1:0sQWfOeY63QTntERDJJ/0SuKK0T1uVSgKCuAROlKEPY= -go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1/go.mod h1:SNgMg+EgDFwmvSmLRTNKC5fegJjB7v23qTQ0XLGUNHk= go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= -go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= -go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -1411,50 +532,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= -go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.28.0/go.mod h1:vEhqr0m4eTc+DWxfsXoXue2GBgV2uUwVznkGIHW/e5w= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.31.0/go.mod h1:PFmBsWbldL1kiWZk9+0LBZz2brhByaGsvp6pRICMlPE= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.32.0/go.mod h1:5eCOqeGphOyz6TsY3ZDNjE33SM/TFAK3RGuCL2naTgY= -go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= -go.opentelemetry.io/otel v1.3.0/go.mod h1:PWIKzi6JCp7sM0k9yZ43VX+T345uNbAkDKwHVjb2PTs= -go.opentelemetry.io/otel v1.6.0/go.mod h1:bfJD2DZVw0LBxghOTlgnlI0CV3hLDu9XF/QKOUXMTQQ= -go.opentelemetry.io/otel v1.6.1/go.mod h1:blzUabWHkX6LJewxvadmzafgh/wnvBSDBdOuwkAtrWQ= -go.opentelemetry.io/otel v1.7.0/go.mod h1:5BdUoMIz5WEs0vt0CUEMtSSaTSHBBVwrhnz7+nrD5xk= -go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.3.0/go.mod h1:VpP4/RMn8bv8gNo9uK7/IMY4mtWLELsS+JIP0inH0h4= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.6.1/go.mod h1:NEu79Xo32iVb+0gVNV8PMd7GoWqnyDXRlj04yFjqz40= -go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.7.0/go.mod h1:M1hVZHNxcbkAlcvrOMlpQ4YOO3Awf+4N2dxkZL3xm04= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.3.0/go.mod h1:hO1KLR7jcKaDDKDkvI9dP/FIhpmna5lkqPUQdEjFAM8= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.6.1/go.mod h1:YJ/JbY5ag/tSQFXzH3mtDmHqzF3aFn3DI/aB1n7pt4w= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.7.0/go.mod h1:ceUgdyfNv4h4gLxHR0WNfDiiVmZFodZhZSbOLhpxqXE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.3.0/go.mod h1:keUU7UfnwWTWpJ+FWnyqmogPa82nuU5VUANFq49hlMY= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.6.1/go.mod h1:UJJXJj0rltNIemDMwkOJyggsvyMG9QHfJeFH0HS5JjM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.7.0/go.mod h1:E+/KKhwOSw8yoPxSSuUHG6vKppkvhN+S1Jc7Nib3k3o= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.3.0/go.mod h1:QNX1aly8ehqqX1LEa6YniTU7VY9I6R3X/oPxhGdTceE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.6.1/go.mod h1:DAKwdo06hFLc0U88O10x4xnb5sc7dDRDqRuiN+io8JE= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.7.0/go.mod h1:aFXT9Ng2seM9eizF+LfKiyPBGy8xIZKwhusC1gIu3hA= -go.opentelemetry.io/otel/metric v0.20.0/go.mod h1:598I5tYlH1vzBjn+BTuhzTCSb/9debfNp6R3s7Pr1eU= -go.opentelemetry.io/otel/metric v0.28.0/go.mod h1:TrzsfQAmQaB1PDcdhBauLMk7nyyg9hm+GoQq/ekE9Iw= -go.opentelemetry.io/otel/metric v0.30.0/go.mod h1:/ShZ7+TS4dHzDFmfi1kSXMhMVubNoP0oIaBp70J6UXU= -go.opentelemetry.io/otel/oteltest v0.20.0/go.mod h1:L7bgKf9ZB7qCwT9Up7i9/pn0PWIa9FqQ2IQ8LoxiGnw= -go.opentelemetry.io/otel/sdk v0.20.0/go.mod h1:g/IcepuwNsoiX5Byy2nNV0ySUF1em498m7hBWC279Yc= -go.opentelemetry.io/otel/sdk v1.3.0/go.mod h1:rIo4suHNhQwBIPg9axF8V9CA72Wz2mKF1teNrup8yzs= -go.opentelemetry.io/otel/sdk v1.6.1/go.mod h1:IVYrddmFZ+eJqu2k38qD3WezFR2pymCzm8tdxyh3R4E= -go.opentelemetry.io/otel/sdk v1.7.0/go.mod h1:uTEOTwaqIVuTGiJN7ii13Ibp75wJmYUDe374q6cZwUU= -go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi+bJK+Dr8NQCh0qGhm1KDnNlE= -go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= -go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= -go.opentelemetry.io/otel/trace v1.3.0/go.mod h1:c/VDhno8888bvQYmbYLqe41/Ldmr/KKunbvWM4/fEjk= -go.opentelemetry.io/otel/trace v1.6.0/go.mod h1:qs7BrU5cZ8dXQHBGxHMOxwME/27YH2qEp4/+tZLLwJE= -go.opentelemetry.io/otel/trace v1.6.1/go.mod h1:RkFRM1m0puWIq10oxImnGEduNBzxiN7TXluRBtE+5j0= -go.opentelemetry.io/otel/trace v1.7.0/go.mod h1:fzLSB9nqR2eXzxPXb2JW9IKE+ScyXA48yyE4TNvoHqU= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= -go.opentelemetry.io/proto/otlp v0.11.0/go.mod h1:QpEjXPrNQzrFDZgoTo49dgHR9RYRSrg3NAKnUGl9YpQ= -go.opentelemetry.io/proto/otlp v0.12.1/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.15.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= -go.opentelemetry.io/proto/otlp v0.16.0/go.mod h1:H7XAot3MsfNsj7EXtrA2q5xSNQ10UqI405h3+duxN4U= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -1462,11 +540,9 @@ go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.9.0 h1:ECmE8Bn/WFTYwEW/bpKD3M8VtR/zQVbavAoalC1PYyE= go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= -go.uber.org/automaxprocs v1.5.1/go.mod h1:BF4eumQw0P9GtnuxxovUd06vwm1o18oMzFtK66vU6XU= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.1.12 h1:gZAh5/EyT/HQwlpkCy6wTpqfH9H8Lz8zbm3dZh+OyzA= -go.uber.org/goleak v1.1.12/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.3.0/go.mod h1:VgVr7evmIr6uPjLBxg28wmKNXyqE9akIJ5XnfpiKl+4= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= @@ -1477,45 +553,28 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.9.1/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.13.0/go.mod h1:zwrFLgMcdUuIBviXEYEH1YKNaOBnKXsx2IPda5bBwHM= -go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.21.0/go.mod h1:wjWOCqI0f2ZZrJF/UufIOkiC8ii6tm1iqIsLo76RfJw= go.uber.org/zap v1.23.0 h1:OjGQ5KQDEUawVHxNwQgPpiypGHOxo2mNZsOqTak4fFY= go.uber.org/zap v1.23.0/go.mod h1:D+nX8jyLsMHMYrln8A0rJjFt/T/9/bGgIhAqxv5URuY= -gocloud.dev v0.27.0 h1:j0WTUsnKTxCsWO7y8T+YCiBZUmLl9w/WIowqAY3yo0g= -gocloud.dev v0.27.0/go.mod h1:YlYKhYsY5/1JdHGWQDkAuqkezVKowu7qbe9aIeUF6p0= -golang.org/x/crypto v0.0.0-20171113213409-9f005a07e0d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181009213950-7c1a557ab941/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= -golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +gocloud.dev v0.26.0 h1:4rM/SVL0lLs+rhC0Gmc+gt/82DBpb7nbpIZKXXnfMXg= +gocloud.dev v0.26.0/go.mod h1:mkUgejbnbLotorqDyvedJO20XcZNTynmSeVSQS9btVg= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190411191339-88737f569e3a/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190820162420-60c769a6c586/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200728195943-123391ffb6de/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20211202192323-5770296d904e/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220511200225-c6db032c6c88/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= +golang.org/x/crypto v0.0.0-20211115234514-b4de73f9ece8/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.0.0-20220331220935-ae2d96664a29/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.1.0 h1:MDRAIl0xIo9Io2xV565hzXHw3zVseKrJKodhohM5CjU= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1554,35 +613,20 @@ golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= @@ -1593,48 +637,28 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/ golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210825183410-e898025ed96a/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211209124913-491a49abca63/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211216030914-fe4d6282115f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220412020605-290c469a71a5/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220617184016-355a448f1bc9/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.0.0-20220802222814-0bcc04d9c69b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= -golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -1655,18 +679,12 @@ golang.org/x/oauth2 v0.0.0-20211005180243-6b3c2da341f1/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/oauth2 v0.0.0-20220608161450-d0670ef3b1eb/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220628200809-02e64fa58f26/go.mod h1:jaDAt6Dkxork7LmZnYtzbRWj0W47D86a3TGe0YHBvmE= -golang.org/x/oauth2 v0.0.0-20220722155238-128564f6959c/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.1.0 h1:isLCZuhj4v+tYv7eskaN4v/TM+A1begWWgyVJDdl1+Y= golang.org/x/oauth2 v0.1.0/go.mod h1:G9FE4dLTsbXUu90h/Pf85g4w1D+SSAgR+q46nJZ8M4A= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -1674,65 +692,32 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20181122145206-62eef0e2fa9b/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190514135907-3a4b5fb9f71f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190522044717-8097e1b27ff5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190801041406-cbf593c0f2f3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190812073006-9eafafc0a87e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191210023423-ac6580df4449/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191220142924-d4481acd189f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200120151820-655fe14d7479/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200124204421-9fbb57f87de9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -1740,91 +725,50 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200728102440-3e129f6d46b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200817155316-9781c653f443/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200828194041-157a740278f4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200909081042-eff7692f9009/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200916030750-2334cc1a136f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200922070232-aee5d888a860/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201112073958-5cba982894dd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201117170446-d9b008d0a637/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201202213521-69691e467435/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210112080510-489259a85091/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210220050731-9a76102bfb43/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210305230114-8fe3ee5dd75b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210315160823-c6e025ad8005/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210426230700-d19ff857e887/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210503080704-8803ae5d1324/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210514084401-e8d321eab015/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210608053332-aa57babbf139/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210903071746-97244b99971b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211210111614-af8b64212486/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220128215802-99c3d69c2c27/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220209214540-3681064d5158/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220310020820-b874c991c1a5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220502124256-b6088ccd6cba/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220610221304-9f5ed59c137d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220615213510-4f61da869c0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220624220833-87e55d714810/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220627191245-f75cf1eec38b/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220731174439-a90be440212d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= -golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1837,53 +781,32 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200416051211-89c76fbcd5d1/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20200630173020-3af7569d3a1e/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220210224613-90d013bbcef8/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20211116232009-f0f3c7e86c11/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20220224211638-0e9765cccd65/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220609170525-579cf78fd858/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20180828015842-6cd1fcedba52/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190422233926-fe54fb35175b/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190425163242-31fd60d6bfdc/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190624222133-a101b041ded4/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db/go.mod h1:jcCCGcm9btYwXyDqrUWc6MKQKKGJCWEQ3AfLSRIbEuI= golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190823170909-c4a336ef6a2f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= @@ -1904,46 +827,31 @@ golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjs golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200505023115-26f46d2f7ef8/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200616133436-c1934b75d054/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= -golang.org/x/tools v0.0.0-20200916195026-c9a70fc28ce3/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201208233053-a543418bbed2/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= -golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= -golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= -golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/xerrors v0.0.0-20190410155217-1f06c39b4373/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190513163551-3ee3066db522/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -golang.org/x/xerrors v0.0.0-20220609144429-65e65417b02f/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk= golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= -google.golang.org/api v0.0.0-20160322025152-9bf6e6e569ff/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0= -google.golang.org/api v0.3.1/go.mod h1:6wY9I6uQWHQ8EM57III9mq/AjF+i8G65rmVagqKMtkk= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1978,22 +886,17 @@ google.golang.org/api v0.58.0/go.mod h1:cAbP2FsxoGVNwtgNAmmn3y5G1TWAiVYRmg4yku3l google.golang.org/api v0.59.0/go.mod h1:sT2boj7M9YJxZzgeZqXogmhfmRWDtPzT31xkieUbuZU= google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/api v0.63.0/go.mod h1:gs4ij2ffTRXwuzzgJl/56BdwJaA194ijkfn++9tDuPo= +google.golang.org/api v0.64.0/go.mod h1:931CdxA8Rm4t6zqTFGSsgwbAEZ2+GMYurbndwSimebM= +google.golang.org/api v0.66.0/go.mod h1:I1dmXYpX7HGwz/ejRxwQp2qj5bFAz93HiCU1C1oYd9M= google.golang.org/api v0.67.0/go.mod h1:ShHKP8E60yPsKNw/w8w+VYaj9H6buA5UqDp8dhbQZ6g= +google.golang.org/api v0.68.0/go.mod h1:sOM8pTpwgflXRhz+oC8H2Dr+UcbMqkPPWNJo88Q7TH8= +google.golang.org/api v0.69.0/go.mod h1:boanBiw+h5c3s+tBPgEzLDRHfFLWV0qXxRHz3ws7C80= google.golang.org/api v0.70.0/go.mod h1:Bs4ZM2HGifEvXwd50TtW70ovgJffJYw2oRCOFU/SkfA= google.golang.org/api v0.71.0/go.mod h1:4PyU6e6JogV1f9eA4voyrTY2batOLdgZ5qZ5HOCc4j8= google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRRyDs= -google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= -google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= -google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= -google.golang.org/api v0.84.0/go.mod h1:NTsGnUFJMYROtiquksZHBWtHfeMC7iYthki7Eq3pa8o= -google.golang.org/api v0.85.0/go.mod h1:AqZf8Ep9uZ2pyTvgL+x0D3Zt0eoT9b5E8fmzfu6FO2g= -google.golang.org/api v0.86.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.90.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= -google.golang.org/api v0.91.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= google.golang.org/api v0.102.0 h1:JxJl2qQ85fRMPNvlZY/enexbxpCjLwGhZUtgfGeQ51I= google.golang.org/api v0.102.0/go.mod h1:3VFl6/fzoA+qNuS1N1/VfXY4LjoXN/wzeIp7TweWwGo= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= @@ -2001,14 +904,11 @@ google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCID google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190522204451-c2c4e71fbf69/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= -google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= @@ -2017,7 +917,6 @@ google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvx google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200117163144-32f20d992d24/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -2026,21 +925,17 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200527145253-8367513e4ece/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20201110150050-8816d57aaa9a/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -2048,7 +943,6 @@ google.golang.org/genproto v0.0.0-20210222152913-aa3ee6e6a81c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20210329143202-679c6ae281ee/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= google.golang.org/genproto v0.0.0-20210429181445-86c259c2b4ab/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= @@ -2077,42 +971,27 @@ google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ6 google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20211221195035-429b39de9b1c/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211223182754-3ac035c7e7cb/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220111164026-67b88f271998/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220114231437-d2e6a121cae0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220126215142-9970aeb2e350/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220201184016-50beb8ab5c44/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220204002441-d6cc3cc0770e/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220207164111-0872dc986b00/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20220211171837-173942840c17/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= +google.golang.org/genproto v0.0.0-20220216160803-4663080d8bc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220218161850-94dd64e39d7c/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220222213610-43724f9ea8cf/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220304144024-325a89244dc8/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220310185008-1973136f34c6/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= google.golang.org/genproto v0.0.0-20220324131243-acbaeb5b85eb/go.mod h1:hAL49I2IFola2sVEjAn7MEwsja0xp51I0tlGAf9hz4E= -google.golang.org/genproto v0.0.0-20220329172620-7be39ac1afc7/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220407144326-9054f6ed7bac/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220413183235-5e96e2839df9/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220414192740-2d67ff6cf2b4/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220421151946-72621c1f0bd3/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220429170224-98d788798c3e/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= -google.golang.org/genproto v0.0.0-20220505152158-f39f71e6c8f3/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220518221133-4f43b3371335/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220523171625-347a074981d8/go.mod h1:RAyBrSAP7Fh3Nc84ghnVLDPuV51xc9agzmm4Ph6i0Q4= -google.golang.org/genproto v0.0.0-20220608133413-ed9918b62aac/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220616135557-88e70c0c3a90/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220617124728-180714bec0ad/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220628213854-d9e0b6570c03/go.mod h1:KEWEmljWE5zPzLBa/oHl6DaEt9LmfH6WtH1OHIvleBA= -google.golang.org/genproto v0.0.0-20220802133213-ce4fa296bf78/go.mod h1:iHe1svFLAZg9VWz891+QbRMwUv9O/1Ww+/mngYeThbc= +google.golang.org/genproto v0.0.0-20220401170504-314d38edb7de/go.mod h1:8w6bsBMX6yCPbAVTeqQHvzxW0EIFigd5lZyahWgyfDo= google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e h1:S9GbmC1iCgvbLyAokVCwiO6tVIrU9Y7c5oMx1V/ki/Y= google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e/go.mod h1:9qHF0xnpdSfF6knlcsnpzUu5y+rpwgbvsyGAZPBMg4s= -google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= -google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.22.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.24.0/go.mod h1:XDChyiUovWa60DnaeDeZmSW86xtLtjtZbwvSiRnRtcA= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= @@ -2135,14 +1014,8 @@ google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnD google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.40.1/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= -google.golang.org/grpc v1.42.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= -google.golang.org/grpc v1.43.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ= -google.golang.org/grpc v1.46.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.46.2/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.47.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= @@ -2162,52 +1035,21 @@ google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/airbrake/gobrake.v2 v2.0.9/go.mod h1:/h5ZAUhDkGaJfjzjKLSjv6zCL6O0LLBxU4K+aSYdM/U= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= -gopkg.in/gcfg.v1 v1.2.3/go.mod h1:yesOnuUOFQAhST5vPY4nbZsb/huCgGGXlipJsBn0b3o= -gopkg.in/gemnasium/logrus-airbrake-hook.v2 v2.1.2/go.mod h1:Xk6kEKp8OKb+X14hQBKWaSkCsqBpgog8nAV2xsGOxlo= gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec/go.mod h1:aPpfJ7XW+gOuirDoZ8gHhLh3kZ1B08FtV2bbmy7Jv3s= -gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= -gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= -gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= -gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= -gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.3.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= -gopkg.in/telebot.v3 v3.0.0/go.mod h1:7rExV8/0mDDNu9epSrDm/8j22KLaActH1Tbee6YjzWg= -gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= -gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= -gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw= -gotest.tools/v3 v3.0.2/go.mod h1:3SzNCllyD9/Y+b5r9JIKQ474KzkZyqLqEfYqMsX94Bk= -gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= -honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= @@ -2215,80 +1057,7 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.20.1/go.mod h1:KqwcCVogGxQY3nBlRpwt+wpAMF/KjaCc7RpywacvqUo= -k8s.io/api v0.20.4/go.mod h1:++lNL1AJMkDymriNniQsWRkMDzRaX2Y/POTUi8yvqYQ= -k8s.io/api v0.20.6/go.mod h1:X9e8Qag6JV/bL5G6bU8sdVRltWKmdHsFUGS3eVndqE8= -k8s.io/api v0.22.5/go.mod h1:mEhXyLaSD1qTOf40rRiKXkc+2iCem09rWLlFwhCEiAs= -k8s.io/api v0.23.5/go.mod h1:Na4XuKng8PXJ2JsploYYrivXrINeTaycCGcYgF91Xm8= -k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg= -k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.4/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= -k8s.io/apimachinery v0.20.6/go.mod h1:ejZXtW1Ra6V1O5H8xPBGz+T3+4gfkTCeExAHKU57MAc= -k8s.io/apimachinery v0.22.1/go.mod h1:O3oNtNadZdeOMxHFVxOreoznohCpy0z6mocxbZr7oJ0= -k8s.io/apimachinery v0.22.5/go.mod h1:xziclGKwuuJ2RM5/rSFQSYAj0zdbci3DH8kj+WvyN0U= -k8s.io/apimachinery v0.23.5/go.mod h1:BEuFMMBaIbcOqVIJqNZJXGFTP4W6AycEpb5+m/97hrM= -k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM= -k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= -k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= -k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= -k8s.io/apiserver v0.22.5/go.mod h1:s2WbtgZAkTKt679sYtSudEQrTGWUSQAPe6MupLnlmaQ= -k8s.io/client-go v0.20.1/go.mod h1:/zcHdt1TeWSd5HoUe6elJmHSQ6uLLgp4bIJHVEuy+/Y= -k8s.io/client-go v0.20.4/go.mod h1:LiMv25ND1gLUdBeYxBIwKpkSC5IsozMMmOOeSJboP+k= -k8s.io/client-go v0.20.6/go.mod h1:nNQMnOvEUEsOzRRFIIkdmYOjAZrC8bgq0ExboWSU1I0= -k8s.io/client-go v0.22.5/go.mod h1:cs6yf/61q2T1SdQL5Rdcjg9J1ElXSwbjSrW2vFImM4Y= -k8s.io/client-go v0.23.5/go.mod h1:flkeinTO1CirYgzMPRWxUCnV0G4Fbu2vLhYCObnt/r4= -k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30= -k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= -k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= -k8s.io/component-base v0.20.4/go.mod h1:t4p9EdiagbVCJKrQ1RsA5/V4rFQNDfRlevJajlGwgjI= -k8s.io/component-base v0.20.6/go.mod h1:6f1MPBAeI+mvuts3sIdtpjljHWBQ2cIy38oBIWMYnrM= -k8s.io/component-base v0.22.5/go.mod h1:VK3I+TjuF9eaa+Ln67dKxhGar5ynVbwnGrUiNF4MqCI= -k8s.io/cri-api v0.17.3/go.mod h1:X1sbHmuXhwaHs9xxYffLqJogVsnI+f6cPRcgPel7ywM= -k8s.io/cri-api v0.20.1/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= -k8s.io/cri-api v0.20.4/go.mod h1:2JRbKt+BFLTjtrILYVqQK5jqhI+XNdF6UiGMgczeBCI= -k8s.io/cri-api v0.20.6/go.mod h1:ew44AjNXwyn1s0U4xCKGodU7J1HzBeZ1MpGrpa5r8Yc= -k8s.io/cri-api v0.23.1/go.mod h1:REJE3PSU0h/LOV1APBrupxrEJqnoxZC8KWzkBUHwrK4= -k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20200428234225-8167cfdcfc14/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= -k8s.io/gengo v0.0.0-20201113003025-83324d819ded/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E= -k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I= -k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= -k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.4.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= -k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= -k8s.io/klog/v2 v2.30.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.40.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.60.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/klog/v2 v2.70.0/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= -k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= -k8s.io/kube-openapi v0.0.0-20201113171705-d219536bb9fd/go.mod h1:WOJ3KddDSol4tAGcJo0Tvi+dK12EcqSLqcWsryKMpfM= -k8s.io/kube-openapi v0.0.0-20210421082810-95288971da7e/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20211109043538-20434351676c/go.mod h1:vHXdDvt9+2spS2Rx9ql3I8tycm3H9FDfdUoIuKCefvw= -k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65/go.mod h1:sX9MT8g7NVZM5lVL/j8QyCCJe8YSMW30QvGZWaCIDIk= -k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42/go.mod h1:Z/45zLw8lUo4wdiUkI+v/ImEGAvu3WatcZl3lPMR4Rk= -k8s.io/kubernetes v1.13.0/go.mod h1:ocZa8+6APFNC2tX1DZASIbocyYT5jHzqFVsY5aoB7Jk= -k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210802155522-efc7438f0176/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210819203725-bdf08cb9a70a/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20211116205334-6203023598ed/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= -nhooyr.io/websocket v1.8.6/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= +nhooyr.io/websocket v1.8.7/go.mod h1:B70DZP8IakI65RVQ51MsWP/8jndNma26DVA/nFSCgW0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.22/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= -sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6/go.mod h1:p4QtZmO4uMYipTQNzagwnNoseA6OxSUutVw05NhYDRs= -sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2/go.mod h1:B+TnT182UBxE84DiCz4CVE26eOSDAeYCpfDnC2kdKMY= -sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.2/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.0.3/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= -sigs.k8s.io/structured-merge-diff/v4 v4.1.2/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/structured-merge-diff/v4 v4.2.1/go.mod h1:j/nl6xW8vLS49O8YvXW1ocPhZawJtm+Yrr7PPRQ0Vg4= -sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= -sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= -sigs.k8s.io/yaml v1.3.0/go.mod h1:GeOyir5tyXNByN85N/dRIT9es5UQNerPYEKK56eTBm8= -sourcegraph.com/sourcegraph/appdash v0.0.0-20190731080439-ebfcffb1b5c0/go.mod h1:hI742Nqp5OhwiqlzhgfbWU4mW4yO10fP+LoT9WOswdU= diff --git a/go.work.sum b/go.work.sum index a4069aab..50913982 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,13 +1,66 @@ +cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= +cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= +cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= -cloud.google.com/go/monitoring v1.4.0 h1:05+IuNMbh40hbxcqQ4SnynbwZbLG1Wc9dysIJxnfv7U= +cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= +cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= +cloud.google.com/go/monitoring v1.5.0 h1:ZltYv8e69fJVga7RTthUBGdx4+Pwz6GRF1V3zylERl4= +cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/pubsub v1.20.0 h1:QuwfH5BpEIE9T3n0YK3PKlsXi/TmHMu593UpOVlWygI= -cloud.google.com/go/trace v1.2.0 h1:oIaB4KahkIUOpLSAAjEJ8y2desbjY/x/RfP4O3KAtTI= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= contrib.go.opencensus.io/exporter/stackdriver v0.13.11 h1:YzmWJ2OT2K3ouXyMm5FmFQPoDs5TfLjx6Xn5x5CLN0I= -contrib.go.opencensus.io/exporter/stackdriver v0.13.12 h1:bjBKzIf7/TAkxd7L2utGaLM78bmUWlCval5K9UeElbY= +contrib.go.opencensus.io/exporter/stackdriver v0.13.13 h1:3KLhsPyyFp1pfZPicg8e1VMSeztIyWm+aE+iZQ8b9Kg= github.com/caarlos0/env/v6 v6.9.1 h1:zOkkjM0F6ltnQ5eBX6IPI41UP/KDGEK7rRPwGCNos8k= -github.com/census-instrumentation/opencensus-proto v0.3.0 h1:t/LhUZLVitR1Ow2YOnduCsavhwFUklBMoGVYUCqmCqk= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jszwec/csvutil v1.6.0 h1:QORXquCT0t8nUKD7utAD4HDmQMgG0Ir9WieZXzpa7ms= @@ -17,13 +70,13 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff github.com/moby/buildkit v0.8.3 h1:vFlwUQ6BZE1loZ8zoZH3fYgmA1djFCS3DrOhCVU6ZZE= github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/prometheus v2.5.0+incompatible h1:7QPitgO2kOFG8ecuRn9O/4L9+10He72rVRJvMXrE9Hg= github.com/rhysd/actionlint v1.6.11 h1:8aD7ozc43RbnKwUmFvRtfW0LTW6f13MTXFDlf+0PNAc= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= @@ -33,12 +86,34 @@ golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZ golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20220909164309-bea034e7d591/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/net v0.0.0-20221012135044-0b7e1fb9d458/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20221014081412-f15817d10f9b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= +golang.org/x/oauth2 v0.0.0-20220822191816-0ebed06d0094/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20220909003341-f21342109be1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= +golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= google.golang.org/api v0.81.0 h1:o8WF5AvfidafWbFjsRyupxyEQJNUWxLZJCK5NXrxZZ8= +google.golang.org/api v0.93.0/go.mod h1:+Sem1dnrKlrXMR/X0bPnMWyluQe4RsNoYfmNLhOIkzw= +google.golang.org/api v0.97.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.98.0/go.mod h1:w7wJQLTM+wvQpNf5JyEcBoxK0RH7EDrh/L4qfsuJ13s= +google.golang.org/api v0.99.0/go.mod h1:1YOf74vkVndF7pG6hIHuINsM7eWwpVTAfNMNiL91A08= google.golang.org/api v0.100.0/go.mod h1:ZE3Z2+ZOr87Rx7dqFsdRQkRBk36kDtp/h+QpHbB7a70= +google.golang.org/genproto v0.0.0-20220822174746-9e6da59bd2fc/go.mod h1:dbqgFATTzChvnt+ujMdZwITVAJHFtfyN1qUhDqEiIlk= +google.golang.org/genproto v0.0.0-20220920201722-2b89144ce006/go.mod h1:ht8XFiar2npT/g4vkk7O0WYS1sHOHbdujxbEp7CJWbw= +google.golang.org/genproto v0.0.0-20220926220553-6981cbe3cfce/go.mod h1:woMGP53BroOrRY3xTxlbr8Y3eB/nzAvvFM83q7kG2OI= +google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqwhZAwq4wsRUaVG555sVgsNmIjRtO7t/JH29U= +google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= +google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= mvdan.cc/sh/v3 v3.4.3 h1:zbuKH7YH9cqU6PGajhFFXZY7dhPXcDr55iN/cUAqpuw= From 5daa44ea3fcde31b15400bccc2e92d285078bbd0 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 16 Nov 2022 12:17:46 +1100 Subject: [PATCH 129/172] Initial version of kubernetes configs for each service. (#242) Signed-off-by: Caleb Brown --- infra/config.yaml | 42 ++++++++++++++++++++ infra/k8s/auth.yaml | 57 +++++++++++++++++++++++++++ infra/k8s/controller.yaml | 81 +++++++++++++++++++++++++++++++++++++++ infra/k8s/transfer.yaml | 45 ++++++++++++++++++++++ infra/k8s/worker.yaml | 56 +++++++++++++++++++++++++++ 5 files changed, 281 insertions(+) create mode 100644 infra/config.yaml create mode 100644 infra/k8s/auth.yaml create mode 100644 infra/k8s/controller.yaml create mode 100644 infra/k8s/transfer.yaml create mode 100644 infra/k8s/worker.yaml diff --git a/infra/config.yaml b/infra/config.yaml new file mode 100644 index 00000000..f7149747 --- /dev/null +++ b/infra/config.yaml @@ -0,0 +1,42 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +project-id: openssf +request-topic-url: gcppubsub://projects/openssf/topics/criticality-score-batch-requests +request-subscription-url: gcppubsub://projects/openssf/subscriptions/criticality-score-batch-worker +bigquery-dataset: criticality_score_cron +bigquery-table: criticality-score-v0 +completion-threshold: 0.99 +shard-size: 10 +webhook-url: +metric-exporter: stackdriver +metric-stackdriver-prefix: criticality-score-cron +result-data-bucket-url: gs://ossf-criticality-score-data + +additional-params: + input-bucket: + url: gs://ossf-criticality-score-url-data + prefix-file: latest + + criticality: + log-env: gcp + log-level: info + dataset: ossf_criticality_score_depsdev + scoring: enabled + scoring-config: config/scorer/pike_depsdev.yml + scoring-column-name: default_score + output-format: json + + scorecard: + # Unused, but must be present to prevent errors. diff --git a/infra/k8s/auth.yaml b/infra/k8s/auth.yaml new file mode 100644 index 00000000..a94216d6 --- /dev/null +++ b/infra/k8s/auth.yaml @@ -0,0 +1,57 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: v1 +kind: Service +metadata: + name: criticality-score-github-service +spec: + selector: + app.kubernetes.io/name: github-auth-server + type: ClusterIP + ports: + - protocol: TCP + port: 80 + targetPort: 8080 +--- + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: criticality-score-github-server +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: github-auth-server + template: + metadata: + labels: + app.kubernetes.io/name: github-auth-server + spec: + containers: + - name: github-auth-server + image: gcr.io/openssf/scorecard-github-server:stable + imagePullPolicy: Always + env: + - name: GITHUB_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: github + key: token + strategy: + type: "RollingUpdate" + rollingUpdate: + maxUnavailable: 1 + maxSurge: 0 diff --git a/infra/k8s/controller.yaml b/infra/k8s/controller.yaml new file mode 100644 index 00000000..cfeb5031 --- /dev/null +++ b/infra/k8s/controller.yaml @@ -0,0 +1,81 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +# This role is used to administer the batch-worker. +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: criticality-score-batch-controller +rules: + - apiGroups: ["apps", "extensions"] + resources: ["deployments"] + resourceNames: ["criticality-score-batch-worker"] + verbs: ["get", "patch"] +--- + +# Bind the role above to the controller, so it can restart the batch-worker. +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: criticality-score-batch-controller +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: criticality-score-batch-controller +subjects: + - kind: ServiceAccount + name: default +--- + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: criticality-score-batch-controller +spec: + # At 02:00UTC on the first day of the Month. + schedule: "0 2 1 * *" + concurrencyPolicy: "Forbid" + jobTemplate: + spec: + template: + spec: + restartPolicy: Never + containers: + - name: controller + image: gcr.io/openssf/scorecard-batch-controller:latest + args: ["--config=/etc/criticality_score/config.yaml"] + imagePullPolicy: Always + env: + - name: GOMEMLIMIT + value: "950MiB" + resources: + limits: + memory: 1Gi + requests: + memory: 1Gi + volumeMounts: + - name: config-volume + mountPath: /etc/criticality_score + readOnly: true + - name: worker-update + image: bitnami/kubectl@sha256:44468c0f5b348e6dcf5e11feb6fdcc969c874bba2856150fe50eb1aacb3bdfee + command: + - "kubectl" + - "rollout" + - "restart" + - "deployment/criticality-score-batch-worker" + volumes: + - name: config-volume + configMap: + name: criticality-score-config diff --git a/infra/k8s/transfer.yaml b/infra/k8s/transfer.yaml new file mode 100644 index 00000000..76e61546 --- /dev/null +++ b/infra/k8s/transfer.yaml @@ -0,0 +1,45 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: criticality-score-bq-transfer +spec: + # At 02:00UTC on the 28th day of the month. + schedule: "0 2 28 * *" + concurrencyPolicy: "Forbid" + jobTemplate: + spec: + template: + spec: + containers: + - name: bq-transfer + image: gcr.io/openssf/scorecard-bq-transfer:latest + args: ["--config=/etc/criticality_score/config.yaml"] + imagePullPolicy: Always + resources: + limits: + memory: 1Gi + requests: + memory: 1Gi + volumeMounts: + - name: config-volume + mountPath: /etc/criticality_score + readOnly: true + volumes: + - name: config-volume + configMap: + name: criticality-score-config + restartPolicy: OnFailure diff --git a/infra/k8s/worker.yaml b/infra/k8s/worker.yaml new file mode 100644 index 00000000..d3427be5 --- /dev/null +++ b/infra/k8s/worker.yaml @@ -0,0 +1,56 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: criticality-score-batch-worker +spec: + replicas: 10 + selector: + matchLabels: + app.kubernetes.io/name: worker + template: + metadata: + labels: + app.kubernetes.io/name: worker + spec: + containers: + - name: worker + image: gcr.io/openssf/criticality-score-collect-signals:latest + args: ["--config=/etc/criticality_score/config.yaml"] + imagePullPolicy: Always + env: + - name: GITHUB_AUTH_SERVER + value: "criticality-score-github-service:80" + resources: + requests: + memory: 5Gi + ephemeral-storage: 100Gi + limits: + memory: 12Gi + ephemeral-storage: 500Gi + volumeMounts: + - name: config-volume + mountPath: /etc/criticality_score + readOnly: true + volumes: + - name: config-volume + configMap: + name: criticality-score-config + strategy: + type: "RollingUpdate" + rollingUpdate: + maxUnavailable: 1 + maxSurge: 1 From a0c7196976416344e60c1a6a0b80fd19ceecc355 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 16 Nov 2022 13:25:49 +1100 Subject: [PATCH 130/172] Fix the chmod in the criticality_score dockerfile. (#244) Signed-off-by: Caleb Brown --- cmd/criticality_score/Dockerfile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/criticality_score/Dockerfile b/cmd/criticality_score/Dockerfile index ac5cf23e..80442aa9 100644 --- a/cmd/criticality_score/Dockerfile +++ b/cmd/criticality_score/Dockerfile @@ -23,8 +23,9 @@ FROM base AS criticality_score ARG TARGETOS ARG TARGETARCH RUN CGO_ENABLED=0 go build ./cmd/criticality_score +RUN chmod -R 0775 /src/config/scorer/* FROM gcr.io/distroless/base:nonroot@sha256:533c15ef2acb1d3b1cd4e58d8aa2740900cae8f579243a53c53a6e28bcac0684 COPY --from=criticality_score /src/criticality_score ./criticality_score -COPY --from=criticality_score --chmod=775 /src/config/scorer/* ./config/scorer/ +COPY --from=criticality_score /src/config/scorer/* ./config/scorer/ ENTRYPOINT ["./criticality_score"] From 8f696b5ea1f5d4f7c214299db41a96ca23d4bf49 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Wed, 16 Nov 2022 14:09:35 +1100 Subject: [PATCH 131/172] Add support for a text format similar to OG python implementation. (#243) To make the command line tool more legible, and to improve feature parity with the Python implementation this change adds a "text" format of the style: key: value Signed-off-by: Caleb Brown --- cmd/criticality_score/README.md | 22 ++++++++-- cmd/criticality_score/main.go | 2 +- internal/signalio/csv.go | 35 ++-------------- internal/signalio/helpers.go | 54 +++++++++++++++++++++++++ internal/signalio/text.go | 72 +++++++++++++++++++++++++++++++++ internal/signalio/type.go | 7 ++++ 6 files changed, 157 insertions(+), 35 deletions(-) create mode 100644 internal/signalio/helpers.go create mode 100644 internal/signalio/text.go diff --git a/cmd/criticality_score/README.md b/cmd/criticality_score/README.md index a69a0ffb..bc42405c 100644 --- a/cmd/criticality_score/README.md +++ b/cmd/criticality_score/README.md @@ -13,6 +13,7 @@ $ gcloud login --update-adc # Sign-in to GCP $ criticality_score \ -workers=1 \ -out=signals.csv \ + -format=csv \ github_projects.txt ``` @@ -108,7 +109,10 @@ See more on GCP #### Output flags -- `-out OUTFILE` specify the `OUTFILE` to use for output. By default `stdout` is used. +- `-format string` specifies the format to use when writing output. Can be + `text` (default), `csv` or `json`. +- `-out OUTFILE` specify the `OUTFILE` to use for output. By default `stdout` + is used. - `-append` appends output to `OUTFILE` if it already exists. - `-force` overwrites `OUTFILE` if it already exists and `-append` is not set. @@ -124,6 +128,16 @@ fail. - `-depsdev-disable` disables the collection of signals from deps.dev. - `-depsdev-dataset string` the BigQuery dataset name to use. Default is `depsdev_analysis`. +#### Scoring flags + +- `-scoring-disable` disables the generation of scores. +- `-scoring-config CONFIG_FILE` specify the `CONFIG_FILE` to use to define how + scores are calculated. See `/config/scorer/` for some valid configs. By + default `/config/scorer/original_pike.yml` is used. +- `-scoring-column` overrides the name of the column used to store the score. + By default the column is named `default_score`, and if `-scoring-config` is + resent the column's name will be based on the config filename. + #### Misc flags - `-log level` set the level of logging. Can be `debug`, `info` (default), `warn` or `error`. @@ -151,13 +165,15 @@ the quota for a single token in about 30-40 minutes. 1. Spin up a compute instance in GCE with lots of RAM and fast network: - Uses GCP's fast/reliable internet connectivity. - - Reduces latency and costs for querying BigQuery data (and perhaps + - Reduces latency and costs for querying BigQuery data (and perhaps GitHub's data too). - - Prevents downtime due to local IT failures. + - Prevents downtime due to local IT failures. 1. Shard the input repository list and run multiple instances on different hosts with different GitHub tokens: - Ensures work progresses even if one instance stops. - Provides additional compute and network resources. +1. Take a look at `collect_signals` and the `\infra\` for a productionized + implementation. ### Q: How do I restart after a failure? diff --git a/cmd/criticality_score/main.go b/cmd/criticality_score/main.go index 0a98dcc2..832d720a 100644 --- a/cmd/criticality_score/main.go +++ b/cmd/criticality_score/main.go @@ -55,7 +55,7 @@ var ( func initFlags() { flag.Var(&logLevel, "log", "set the `level` of logging.") flag.TextVar(&logEnv, "log-env", log.DefaultEnv, "set logging `env`.") - flag.TextVar(&formatType, "format", signalio.WriterTypeCSV, "set the output format.") + flag.TextVar(&formatType, "format", signalio.WriterTypeText, "set the output format. Choices are text, json or csv.") outfile.DefineFlags(flag.CommandLine, "out", "force", "append", "OUTFILE") flag.Usage = func() { cmdName := path.Base(os.Args[0]) diff --git a/internal/signalio/csv.go b/internal/signalio/csv.go index efa96bb7..4a5b3dd0 100644 --- a/internal/signalio/csv.go +++ b/internal/signalio/csv.go @@ -33,45 +33,18 @@ type csvWriter struct { mu sync.Mutex } -func headerFromSignalSets(sets []signal.Set, extra []string) []string { - var hs []string - for _, s := range sets { - if err := signal.ValidateSet(s); err != nil { - panic(err) - } - hs = append(hs, signal.SetFields(s, true)...) - } - // Append all the extra fields - hs = append(hs, extra...) - return hs -} - func CSVWriter(w io.Writer, emptySets []signal.Set, extra ...string) Writer { return &csvWriter{ - header: headerFromSignalSets(emptySets, extra), + header: fieldsFromSignalSets(emptySets, extra), w: csv.NewWriter(w), } } // WriteSignals implements the Writer interface. func (w *csvWriter) WriteSignals(signals []signal.Set, extra ...Field) error { - values := make(map[string]string) - for _, s := range signals { - // Get all of the signal data from the set and serialize it. - for k, v := range signal.SetAsMap(s, true) { - if s, err := marshalValue(v); err != nil { - return fmt.Errorf("failed to write field %s: %w", k, err) - } else { - values[k] = s - } - } - } - for _, f := range extra { - if s, err := marshalValue(f.Value); err != nil { - return fmt.Errorf("failed to write field %s: %w", f.Key, err) - } else { - values[f.Key] = s - } + values, err := marshalToMap(signals, extra...) + if err != nil { + return err } return w.writeRecord(values) } diff --git a/internal/signalio/helpers.go b/internal/signalio/helpers.go new file mode 100644 index 00000000..d1335489 --- /dev/null +++ b/internal/signalio/helpers.go @@ -0,0 +1,54 @@ +// 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. + +package signalio + +import ( + "fmt" + + "github.com/ossf/criticality_score/internal/collector/signal" +) + +func fieldsFromSignalSets(sets []signal.Set, extra []string) []string { + var fields []string + for _, s := range sets { + if err := signal.ValidateSet(s); err != nil { + panic(err) + } + fields = append(fields, signal.SetFields(s, true)...) + } + // Append all the extra fields + fields = append(fields, extra...) + return fields +} + +func marshalToMap(signals []signal.Set, extra ...Field) (map[string]string, error) { + values := make(map[string]string) + for _, s := range signals { + // Get all of the signal data from the set and serialize it. + for k, v := range signal.SetAsMap(s, true) { + if s, err := marshalValue(v); err != nil { + return nil, fmt.Errorf("failed to write field %s: %w", k, err) + } else { + values[k] = s + } + } + } + for _, f := range extra { + if s, err := marshalValue(f.Value); err != nil { + return nil, fmt.Errorf("failed to write field %s: %w", f.Key, err) + } else { + values[f.Key] = s + } + } + return values, nil +} diff --git a/internal/signalio/text.go b/internal/signalio/text.go new file mode 100644 index 00000000..ad76d078 --- /dev/null +++ b/internal/signalio/text.go @@ -0,0 +1,72 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package signalio + +import ( + "fmt" + "io" + "sync" + + "github.com/ossf/criticality_score/internal/collector/signal" +) + +type textWriter struct { + w io.Writer + fields []string + firstRecordWritten bool + + // Prevents concurrent writes to w. + mu sync.Mutex +} + +func TextWriter(w io.Writer, emptySets []signal.Set, extra ...string) Writer { + return &textWriter{ + w: w, + fields: fieldsFromSignalSets(emptySets, extra), + } +} + +// WriteSignals implements the Writer interface. +func (w *textWriter) WriteSignals(signals []signal.Set, extra ...Field) error { + values, err := marshalToMap(signals, extra...) + if err != nil { + return err + } + return w.writeRecord(values) +} + +func (w *textWriter) writeRecord(values map[string]string) error { + w.mu.Lock() + defer w.mu.Unlock() + + // Output a newline between records if this isn't the first record. + if w.firstRecordWritten { + _, err := fmt.Fprintln(w.w, "") + if err != nil { + return err + } + } else { + w.firstRecordWritten = true + } + + for _, field := range w.fields { + val := values[field] + _, err := fmt.Fprintf(w.w, "%s: %s\n", field, val) + if err != nil { + return err + } + } + return nil +} diff --git a/internal/signalio/type.go b/internal/signalio/type.go index 03ee77ee..9d5777c9 100644 --- a/internal/signalio/type.go +++ b/internal/signalio/type.go @@ -27,6 +27,7 @@ type WriterType int const ( WriterTypeCSV = WriterType(iota) WriterTypeJSON + WriterTypeText ) var ErrorUnknownWriterType = errors.New("unknown writer type") @@ -47,6 +48,8 @@ func (t WriterType) MarshalText() ([]byte, error) { return []byte("csv"), nil case WriterTypeJSON: return []byte("json"), nil + case WriterTypeText: + return []byte("text"), nil default: return []byte{}, ErrorUnknownWriterType } @@ -59,6 +62,8 @@ func (t *WriterType) UnmarshalText(text []byte) error { *t = WriterTypeCSV case bytes.Equal(text, []byte("json")): *t = WriterTypeJSON + case bytes.Equal(text, []byte("text")): + *t = WriterTypeText default: return ErrorUnknownWriterType } @@ -73,6 +78,8 @@ func (t *WriterType) New(w io.Writer, emptySets []signal.Set, extra ...string) W return CSVWriter(w, emptySets, extra...) case WriterTypeJSON: return JSONWriter(w) + case WriterTypeText: + return TextWriter(w, emptySets, extra...) default: return nil } From d8da6d1f8beef0d5a741e8193fb18e987491f1f5 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 18 Nov 2022 13:04:21 +1100 Subject: [PATCH 132/172] Make more of the Python impl deprecated. (#246) * Bump the Py version. * Show a deprecation message. * Update CONTRIBUTING guide to include up-to-date details. * Remove any mention of Python from the primary README.md file. Signed-off-by: Caleb Brown --- CONTRIBUTING.md | 16 ++--- README.md | 130 ++++++++++++++++++++------------------- criticality_score/run.py | 12 ++++ setup.py | 4 +- 4 files changed, 88 insertions(+), 74 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4e9a89e3..257c4365 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,8 +41,9 @@ $ cd criticality_score 1. Find or create an [issue](https://github.com/ossf/criticality_score/issues) 1. Make code changes to: + - the [collect_signals CLI tool](https://github.com/ossf/criticality_score/tree/main/cmd/collect_signals) - the [GitHub enumerator](https://github.com/ossf/criticality_score/tree/main/cmd/enumerate_github) - - the [signal collector](https://github.com/ossf/criticality_score/tree/main/cmd/collect_signals) + - the [signal collector worker](https://github.com/ossf/criticality_score/tree/main/cmd/collect_signals) - the [scorer](https://github.com/ossf/criticality_score/tree/main/cmd/scorer) - the scorer [algorithm configuration](https://github.com/ossf/criticality_score/tree/main/config/scorer) @@ -51,15 +52,10 @@ $ cd criticality_score ```shell $ export GITHUB_TOKEN=ghp_x # the personal access token created above -$ echo "https://github.com/{ a repo }" | \ - go run ./cmd/collect_signals \ - -log=debug \ - -depsdev-disable \ # remove if you have a GCP account configured - - - | \ - go run ./cmd/scorer \ - -log=debug \ - -config=config/scorer/original_pike.yml \ - - - +$ go run ./cmd/criticality_score \ + -log=debug \ + -depsdev-disable \ # remove if you have a GCP account configured + "https://github.com/{ a repo }" ``` Note: Each of the tools listed above can be run individually and has their own README. diff --git a/README.md b/README.md index 99cbd5a7..3b6f3e64 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ This project is maintained by members of the [Securing Critical Projects WG](https://github.com/ossf/wg-securing-critical-projects). ## Goals + 1. Generate a **criticality score** for every open source project. 1. Create a list of critical projects that the open source community depends on. @@ -49,40 +50,36 @@ open source project: The program only requires one argument to run, the name of the repo: ```shell -$ pip3 install criticality-score - -$ criticality_score --repo github.com/kubernetes/kubernetes -name: kubernetes -url: https://github.com/kubernetes/kubernetes -language: Go -description: Production-Grade Container Scheduling and Management -created_since: 87 -updated_since: 0 -contributor_count: 3999 -watchers_count: 79583 -org_count: 5 -commit_frequency: 97.2 -recent_releases_count: 70 -updated_issues_count: 5395 -closed_issues_count: 3062 -comment_frequency: 5.5 -dependents_count: 454393 -criticality_score: 0.99107 +$ go install github.com/ossf/criticality_score/cmd/criticality_score + +$ criticality_score github.com/kubernetes/kubernetes +repo.name: kubernetes +repo.url: https://github.com/kubernetes/kubernetes +repo.language: Go +repo.license: Apache License 2.0 +legacy.created_since: 87 +legacy.updated_since: 0 +legacy.contributor_count: 3999 +legacy.watchers_count: 79583 +legacy.org_count: 5 +legacy.commit_frequency: 97.2 +legacy.recent_releases_count: 70 +legacy.updated_issues_count: 5395 +legacy.closed_issues_count: 3062 +legacy.comment_frequency: 5.5 +legacy.dependents_count: 454393 +default_score: 0.99107 ``` -You can add your own parameters to the criticality score calculation. For -example, you can add internal project usage data to re-adjust the project's -criticality score for your prioritization needs. This can be done by adding -the `--params :: ...` -argument on the command line. You cannot specify the parameter names and -these won't be listed in the results but they will be included in the -score calculation. +The score can be changed by using the `-scoring-config` parameter and supplying +a different configuration file to specify how the score is calculated. + +By default the `original_pike.yml` configuration is used to calculate the score. +However, other config files can be supplied to produce different scores. See +[config/scorer](`https://github.com/ossf/criticality_score/blob/main/config/scorer`) for more. -You can override the default values for the weight and threshold of the -built-in parameters to match your needs. This can be done by adding the -`--overrides :: ...` -argument on the command line, where param1_name refers to the name of the -parameter you want to override. +Feel free to copy one of the configurations and adjust the weights and +thresholds to suit your needs. ### Authentication @@ -103,6 +100,8 @@ export GITHUB_AUTH_TOKEN= set GITHUB_AUTH_TOKEN= ``` + + ### Formatting Results -There are three formats currently: `default`, `json`, and `csv`. Others may be added in the future. +There are three formats currently: `text`, `json`, and `csv`. Others may be added in the future. + +These may be specified with the `-format` flag. + +## Other Commands -These may be specified with the `--format` flag. +The criticality score project also has other commands for generating and +working with criticality score data. + +- [`enumerate_github`](https://github.com/ossf/criticality_score/blob/main/cmd/enumerate_github): + a tool for accurately collecting a set of GitHub repos with a minimum number of stars +- [`collect_signals`](https://github.com/ossf/criticality_score/blob/main/cmd/collect_signals): + a worker for collecting raw signals at scale by leveraging the + [Scorecard project's](https://github.com/ossf/scorecard) infrastructure. +- [`scorer`](https://github.com/ossf/criticality_score/blob/main/cmd/scorer): + a tool for recalculating criticality scores based on an input CSV file. ## Public Data -If you're only interested in seeing a list of critical projects with their -criticality score, we publish them in `csv` format. +If you're interested in seeing a list of critical projects with their criticality +score, we publish them in `csv` format and a BigQuery dataset. -This data is available on Google Cloud Storage and can be downloaded via the -[`gsutil`](https://cloud.google.com/storage/docs/gsutil_install) -command-line tool or the web browser -[here](https://commondatastorage.googleapis.com/ossf-criticality-score/index.html). +This data is generated using a production instance of the criticality score +project running in GCP. Details for how this is deployed can be found in the +[infra](https://github.com/ossf/criticality_score/blob/main/infra) directory. **NOTE**: Currently, these lists are derived from **projects hosted on GitHub ONLY**. We do plan to expand them in near future to account for projects hosted on other source control systems. -```shell -$ gsutil ls gs://ossf-criticality-score/*.csv -gs://ossf-criticality-score/c_top_200.csv -gs://ossf-criticality-score/cplusplus_top_200.csv -gs://ossf-criticality-score/csharp_top_200.csv -gs://ossf-criticality-score/go_top_200.csv -gs://ossf-criticality-score/java_top_200.csv -gs://ossf-criticality-score/js_top_200.csv -gs://ossf-criticality-score/php_top_200.csv -gs://ossf-criticality-score/python_top_200.csv -gs://ossf-criticality-score/ruby_top_200.csv -gs://ossf-criticality-score/rust_top_200.csv -gs://ossf-criticality-score/shell_top_200.csv -``` +### CSV data -This data is generated using this -[generator script](https://github.com/ossf/criticality_score/blob/main/criticality_score/generate.py). -For example, to generate a list of top 200 C language projects, run: +The data is available on Google Cloud Storage and can be downloaded via: -```shell -$ pip3 install python-gitlab PyGithub -$ python3 -u -m criticality_score.generate \ - --language c --count 200 --sample-size 5000 --output-dir output -``` +- web browser: [commondatastorage.googleapis.com/ossf-criticality-score/index.html](https://commondatastorage.googleapis.com/ossf-criticality-score/index.html) +- [`gsutil`](https://cloud.google.com/storage/docs/gsutil_install) +command-line tool: `gsutil ls gs://ossf-criticality-score/` + +### BigQuery Dataset -We have also aggregated the results over 100K repositories in GitHub (language-independent) and are available for download [here](https://www.googleapis.com/download/storage/v1/b/ossf-criticality-score/o/all.csv?generation=1614554714813772&alt=media). +This data is available in the public [BigQuery dataset](https://console.cloud.google.com/bigquery?d=criticality_score_cron&p=openssf&t=criticality-score-v0-latest&page=table). + +With a GCP account you can run queries across the data. For example, here is a query returning the top 100 repos by score: + +```sql + SELECT repo.url, default_score + FROM `openssf.criticality_score_cron.criticality-score-v0-latest` +ORDER BY default_score DESC + LIMIT 100; +``` ## Contributing diff --git a/criticality_score/run.py b/criticality_score/run.py index 82f8705b..9851c69a 100644 --- a/criticality_score/run.py +++ b/criticality_score/run.py @@ -24,6 +24,7 @@ import threading import time import urllib +import warnings import github import gitlab @@ -31,8 +32,19 @@ from .defaults import * # pylint: disable=wildcard-import + logger = logging.getLogger() +_DEPRECATION_MESSAGE = """ +The python version of criticality-score is deprecated and will +no longer receive updates. + +A Go version exists and is under active development and should be used instead. +See https://github.com/ossf/criticality_score for more details. +""" +warnings.simplefilter("always", DeprecationWarning) +warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning) + _CACHED_GITHUB_TOKEN = None _CACHED_GITHUB_TOKEN_OBJ = None diff --git a/setup.py b/setup.py index 183b1b96..731a58bc 100644 --- a/setup.py +++ b/setup.py @@ -19,14 +19,14 @@ setuptools.setup( name='criticality_score', - version='1.0.7', + version='1.0.8', author='Abhishek Arya', author_email='', description='Gives criticality score for an open source project', long_description=long_description, long_description_content_type='text/markdown', url='https://github.com/ossf/criticality-score', - packages=setuptools.find_packages(), + packages=setuptools.find_packages(include=["criticality_score"]), classifiers=[ 'Programming Language :: Python :: 3', 'License :: OSI Approved :: Apache Software License', From 18a167d69271cf6b0c8f1519a23b1b414161db44 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 21 Nov 2022 09:10:38 +1100 Subject: [PATCH 133/172] Support for CSV dumps from the production worker (#245) Introduce csv output alongside json output and an aggregation tool. - collect_signals now can (optionally) output a bunch of csv shard files. - csv_transfer reads csv shard files and aggregates them together and writes them out to another bucket. - adds cloudbuild and k8s config for csv_transfer. Signed-off-by: Caleb Brown --- Makefile | 4 +- cmd/collect_signals/main.go | 37 +-- cmd/collect_signals/worker.go | 30 ++- cmd/csv_transfer/Dockerfile | 29 +++ cmd/csv_transfer/README.md | 4 + cmd/csv_transfer/main.go | 223 ++++++++++++++++++ go.mod | 3 +- go.sum | 6 +- go.work.sum | 34 ++- infra/cloudbuild/csv_transfer/cloudbuild.yaml | 22 ++ infra/config.yaml | 8 +- infra/k8s/csv_transfer.yaml | 45 ++++ internal/log/config.go | 35 +++ 13 files changed, 436 insertions(+), 44 deletions(-) create mode 100644 cmd/csv_transfer/Dockerfile create mode 100644 cmd/csv_transfer/README.md create mode 100644 cmd/csv_transfer/main.go create mode 100644 infra/cloudbuild/csv_transfer/cloudbuild.yaml create mode 100644 infra/k8s/csv_transfer.yaml diff --git a/Makefile b/Makefile index 3439830c..2c73abf7 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ lint: ## Run linter lint: $(GOLANGCI_LINT) $(GOLANGCI_LINT) run -c .golangci.yml -docker-targets = build/docker/enumerate-github build/docker/criticality-score build/docker/collect-signals +docker-targets = build/docker/enumerate-github build/docker/criticality-score build/docker/collect-signals build/docker/csv-transfer .PHONY: build/docker $(docker-targets) build/docker: $(docker-targets) ## Build all docker targets build/docker/collect-signals: @@ -42,6 +42,8 @@ build/docker/criticality-score: DOCKER_BUILDKIT=1 docker build . -f cmd/criticality_score/Dockerfile --tag $(IMAGE_NAME)-cli build/docker/enumerate-github: DOCKER_BUILDKIT=1 docker build . -f cmd/enumerate_github/Dockerfile --tag $(IMAGE_NAME)-enumerate-github +build/docker/csv-transfer: + DOCKER_BUILDKIT=1 docker build . -f cmd/csv_transfer/Dockerfile --tag $(IMAGE_NAME)-csv-transfer .PHONY: install/deps install/deps: ## Installs all dependencies during development and building diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 3f6b8029..1090576d 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -27,7 +27,6 @@ import ( "github.com/ossf/criticality_score/internal/collector" log "github.com/ossf/criticality_score/internal/log" - "github.com/ossf/criticality_score/internal/signalio" ) const defaultLogLevel = zapcore.InfoLevel @@ -45,37 +44,13 @@ func main() { panic(err) } - // Extract the log environment from the config, if it exists. - logEnv := log.DefaultEnv - if val := criticalityConfig["log-env"]; val != "" { - if err := logEnv.UnmarshalText([]byte(val)); err != nil { - panic(err) - } - } - - // Extract the log level from the config, if it exists. - logLevel := defaultLogLevel - if val := criticalityConfig["log-level"]; val != "" { - if err := logLevel.Set(val); err != nil { - panic(err) - } - } - // Setup the logger. - logger, err := log.NewLogger(logEnv, logLevel) + logger, err := log.NewLoggerFromConfigMap(log.DefaultEnv, defaultLogLevel, criticalityConfig) if err != nil { panic(err) } defer logger.Sync() - // Parse the output format. - formatType := signalio.WriterTypeCSV - if val := criticalityConfig["output-format"]; val != "" { - if err := formatType.UnmarshalText([]byte(val)); err != nil { - panic(err) - } - } - // Extract the GCP project ID. gcpProjectID, err := config.GetProjectID() if err != nil { @@ -106,7 +81,13 @@ func main() { scoringConfigFile := criticalityConfig["scoring-config"] scoringColumnName := criticalityConfig["scoring-column-name"] - // TODO: capture metrics similar to scorecard/cron/worker + // Extract the CSV bucket URL. Currently uses the raw result bucket url. + // TODO: use a more sensible configuration entry. + csvBucketURL, err := config.GetRawResultDataBucketURL() + if err != nil { + logger.With(zap.Error(err)).Error("Failed to read CSV bucket URL. Ignoring.") + csvBucketURL = "" + } // Bump the # idle conns per host http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 5 @@ -118,7 +99,7 @@ func main() { collector.GCPDatasetName(gcpDatasetName), } - w, err := NewWorker(context.Background(), logger, formatType, scoringEnabled, scoringConfigFile, scoringColumnName, opts) + w, err := NewWorker(context.Background(), logger, scoringEnabled, scoringConfigFile, scoringColumnName, csvBucketURL, opts) if err != nil { // Fatal exits. logger.With(zap.Error(err)).Fatal("Failed to create worker") diff --git a/cmd/collect_signals/worker.go b/cmd/collect_signals/worker.go index fefdb271..1f938eeb 100644 --- a/cmd/collect_signals/worker.go +++ b/cmd/collect_signals/worker.go @@ -29,7 +29,7 @@ type collectWorker struct { c *collector.Collector s *scorer.Scorer scoreColumnName string - writerType signalio.WriterType + csvBucketURL string } // Process implements the worker.Worker interface. @@ -51,8 +51,12 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq extras = append(extras, w.scoreColumnName) } extras = append(extras, collectionDateColumnName) - var output bytes.Buffer - out := w.writerType.New(&output, w.c.EmptySets(), extras...) + + var jsonOutput bytes.Buffer + jsonOut := signalio.JSONWriter(&jsonOutput) + + var csvOutput bytes.Buffer + csvOut := signalio.CSVWriter(&csvOutput, w.c.EmptySets(), extras...) // Iterate through the repos in this shard. for _, repo := range req.GetRepos() { @@ -99,15 +103,25 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq }) // Write the signals to storage. - if err := out.WriteSignals(ss, extras...); err != nil { + if err := jsonOut.WriteSignals(ss, extras...); err != nil { + return fmt.Errorf("failed writing signals: %w", err) + } + if err := csvOut.WriteSignals(ss, extras...); err != nil { return fmt.Errorf("failed writing signals: %w", err) } } + // Write to the csv bucket if it is set. + if w.csvBucketURL != "" { + if err := data.WriteToBlobStore(ctx, w.csvBucketURL, filename, csvOutput.Bytes()); err != nil { + return fmt.Errorf("error writing csv to blob store") + } + } + // Write to the canonical bucket last. The presence of the file indicates // the job was completed. See scorecard's worker package for details. - if err := data.WriteToBlobStore(ctx, bucketURL, filename, output.Bytes()); err != nil { - return fmt.Errorf("error writing to blob store: %w", err) + if err := data.WriteToBlobStore(ctx, bucketURL, filename, jsonOutput.Bytes()); err != nil { + return fmt.Errorf("error writing json to blob store: %w", err) } logger.Info("Shard written successfully") @@ -170,7 +184,7 @@ func getMetricsExporter() (monitoring.Exporter, error) { return exporter, nil } -func NewWorker(ctx context.Context, logger *zap.Logger, writerType signalio.WriterType, scoringEnabled bool, scoringConfigFile, scoringColumn string, collectOpts []collector.Option) (*collectWorker, error) { +func NewWorker(ctx context.Context, logger *zap.Logger, scoringEnabled bool, scoringConfigFile, scoringColumn, csvBucketURL string, collectOpts []collector.Option) (*collectWorker, error) { logger.Info("Initializing worker") c, err := collector.New(ctx, logger, collectOpts...) @@ -199,7 +213,7 @@ func NewWorker(ctx context.Context, logger *zap.Logger, writerType signalio.Writ c: c, s: s, scoreColumnName: scoringColumn, - writerType: writerType, exporter: exporter, + csvBucketURL: csvBucketURL, }, nil } diff --git a/cmd/csv_transfer/Dockerfile b/cmd/csv_transfer/Dockerfile new file mode 100644 index 00000000..578c931a --- /dev/null +++ b/cmd/csv_transfer/Dockerfile @@ -0,0 +1,29 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +FROM golang@sha256:122f3484f844467ebe0674cf57272e61981770eb0bc7d316d1f0be281a88229f AS base +WORKDIR /src +ENV CGO_ENABLED=0 +COPY go.mod go.sum ./ +RUN go mod download +COPY . ./ + +FROM base AS csv_transfer +ARG TARGETOS +ARG TARGETARCH +RUN CGO_ENABLED=0 go build ./cmd/csv_transfer + +FROM gcr.io/distroless/base:nonroot@sha256:533c15ef2acb1d3b1cd4e58d8aa2740900cae8f579243a53c53a6e28bcac0684 +COPY --from=csv_transfer /src/csv_transfer ./csv_transfer +ENTRYPOINT ["./csv_transfer"] diff --git a/cmd/csv_transfer/README.md b/cmd/csv_transfer/README.md new file mode 100644 index 00000000..227e2099 --- /dev/null +++ b/cmd/csv_transfer/README.md @@ -0,0 +1,4 @@ +# CSV Transfer + +This tool runs across the CSV output for each shard produced by +`collect_signals` and aggregates the output into a single CSV file. diff --git a/cmd/csv_transfer/main.go b/cmd/csv_transfer/main.go new file mode 100644 index 00000000..de6f1cda --- /dev/null +++ b/cmd/csv_transfer/main.go @@ -0,0 +1,223 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package main + +import ( + "bytes" + "context" + "encoding/csv" + "flag" + "fmt" + "strings" + + "github.com/ossf/scorecard/v4/cron/config" + "github.com/ossf/scorecard/v4/cron/data" + "go.uber.org/zap" + "go.uber.org/zap/zapcore" + "golang.org/x/exp/slices" + + "github.com/ossf/criticality_score/internal/log" +) + +const defaultLogLevel = zapcore.InfoLevel + +func processShardSet(ctx context.Context, logger *zap.Logger, summary *data.ShardSummary, srcBucket, destBucket, destFilename string, threshold float64) (int, error) { + logger = logger.With(zap.Time("creation_time", summary.CreationTime())) + if summary.IsTransferred() || !summary.IsCompleted(threshold) { + logger.With( + zap.Bool("is_transferred", summary.IsTransferred()), + zap.Bool("is_completed", summary.IsCompleted(threshold)), + ).Debug("Skipping") + return 0, nil + } + + logger.Info("Transferring...") + + // Scan the prefix for all the keys with a given prefix. + // This will also include the + keys, err := data.GetBlobKeysWithPrefix(ctx, srcBucket, data.GetBlobFilename("", summary.CreationTime())) + if err != nil { + return 0, fmt.Errorf("fetching blob keys by prefix: %w", err) + } + + var out bytes.Buffer + w := csv.NewWriter(&out) + + // Stores the first header row we encounter. It is used to generate the + // header row for the aggregate CSV, and to validate all the CSV files + // have the same columns. + var firstHeader []string + + // Store the total number of records processed. + var total int + + // Iterate through keys. + for _, key := range keys { + keyLogger := logger.With(zap.String("blob_key", key)) + + _, filename, err := data.ParseBlobFilename(key) + if err != nil { + return 0, fmt.Errorf("parsing key %s into blob filename: %w", key, err) + } + + // Filter out any keys that don't point to the shard files containing the data. + if !strings.HasPrefix(filename, "shard-") { + keyLogger.Debug("Skipping key") + continue + } + + keyLogger.Debug("Processing key") + + // Grab the shard CSV data. + content, err := data.GetBlobContent(ctx, srcBucket, key) + if err != nil { + return 0, fmt.Errorf("fetching blob content for key %s: %w", key, err) + } + + // Wrap the data in a buffer and CSV Reader to make it easy to consume. + b := bytes.NewBuffer(content) + r := csv.NewReader(b) + + header, err := r.Read() + if err != nil { + return 0, fmt.Errorf("reading header row for key %s: %w", key, err) + } + + // Ensure the CSV headers are consistent. + if firstHeader == nil { + firstHeader = header + if err := w.Write(header); err != nil { + return 0, fmt.Errorf("writing header row from %s: %w", key, err) + } + } + + // Ensure the headers are consistent to avoid columns not matching. + if !slices.Equal(firstHeader, header) { + return 0, fmt.Errorf("key %s header does not match first header", key) + } + + records, err := r.ReadAll() + if err != nil { + return 0, fmt.Errorf("reading all records for key %s: %w", key, err) + } + total += len(records) + + if err := w.WriteAll(records); err != nil { + return 0, fmt.Errorf("writing all records for key %s: %w", key, err) + } + } + + // Store the aggregated CSV file. + if err := data.WriteToBlobStore(ctx, destBucket, data.GetBlobFilename(destFilename, summary.CreationTime()), out.Bytes()); err != nil { + return 0, fmt.Errorf("writing aggregate csv: %w", err) + } + + // Mark the summary as completed so it doesn't get reprocessed again. + if err := summary.MarkTransferred(ctx, srcBucket); err != nil { + return 0, fmt.Errorf("marking shards as transferred: %w", err) + } + + logger.With(zap.Int("total_records", total)).Info("Transfer complete") + return total, nil +} + +func main() { + flag.Parse() + + if err := config.ReadConfig(); err != nil { + panic(err) + } + + // Extract the criticality score specific variables in the config. + criticalityConfig, err := config.GetCriticalityValues() + if err != nil { + panic(err) + } + + // Setup the logger. + logger, err := log.NewLoggerFromConfigMap(log.DefaultEnv, defaultLogLevel, criticalityConfig) + if err != nil { + panic(err) + } + defer logger.Sync() + + completionThreshold, err := config.GetCompletionThreshold() + if err != nil { + // Fatal exits. + logger.With(zap.Error(err)).Fatal("Failed to get completion threshold") + } + + // TODO: use a more sensible configuration entry. + srcBucketURL, err := config.GetRawResultDataBucketURL() + if err != nil { + // Fatal exits. + logger.With(zap.Error(err)).Fatal("Failed to get raw data bucket URL") + } + + destBucketURL := criticalityConfig["csv-transfer-bucket-url"] + if destBucketURL == "" { + logger.Fatal("Failed to get CSV transfer bucket URL") + } + + destFilename := criticalityConfig["csv-transfer-filename"] + if destFilename == "" { + logger.Fatal("Failed to get CSV transfer filename") + } + + logger = logger.With( + zap.String("src_bucket", srcBucketURL), + zap.String("dest_bucket", destBucketURL), + zap.String("dest_filename", destFilename), + ) + + ctx := context.Background() + + bucketSummary, err := data.GetBucketSummary(ctx, srcBucketURL) + if err != nil { + // Fatal exits. + logger.With(zap.Error(err)).Fatal("Failed to get bucket summary") + } + shards := bucketSummary.Shards() + + numShardSets := len(shards) + var processShardSets int + var erroredShardSets int + var totalRecords int + + logger.With(zap.Int("number_shard_sets", numShardSets)).Info("Found shards") + + for _, summary := range shards { + if n, err := processShardSet(ctx, logger, summary, srcBucketURL, destBucketURL, destFilename, completionThreshold); err != nil { + // Show an error, but continue processing. + logger.With( + zap.Error(err), + zap.Time("creation_time", summary.CreationTime()), + ).Error("Failed to process shard set") + erroredShardSets++ + } else if n > 0 { + processShardSets++ + totalRecords += n + } + } + + // Output a bunch of useful metrics. + logger.With( + zap.Int("number_shard_sets", numShardSets), + zap.Int("processed_shard_sets", processShardSets), + zap.Int("errored_shard_sets", erroredShardSets), + zap.Int("skipped_shard_sets", numShardSets-processShardSets-erroredShardSets), + zap.Int("total_records_processed", totalRecords), + ).Info("Done") +} diff --git a/go.mod b/go.mod index c1811b52..fa605832 100644 --- a/go.mod +++ b/go.mod @@ -9,11 +9,12 @@ require ( github.com/google/go-cmp v0.5.9 github.com/google/go-github/v47 v47.1.0 github.com/iancoleman/strcase v0.2.0 - github.com/ossf/scorecard/v4 v4.8.1-0.20221113231904-ca55bd0e67ea + github.com/ossf/scorecard/v4 v4.8.1-0.20221116210408-a78b27d14e74 github.com/shurcooL/githubv4 v0.0.0-20220115235240-a14260e6f8a2 go.opencensus.io v0.23.0 go.uber.org/zap v1.23.0 gocloud.dev v0.26.0 + golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 google.golang.org/api v0.102.0 gopkg.in/yaml.v3 v3.0.1 ) diff --git a/go.sum b/go.sum index 611a9ae1..5a398dbf 100644 --- a/go.sum +++ b/go.sum @@ -472,8 +472,8 @@ github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lN github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5/go.mod h1:caMODM3PzxT8aQXRPkAt8xlV/e7d7w8GM5g0fa5F0D8= github.com/onsi/ginkgo/v2 v2.5.0 h1:TRtrvv2vdQqzkwrQ1ke6vtXf7IK34RBUJafIy1wMwls= github.com/onsi/gomega v1.24.0 h1:+0glovB9Jd6z3VR+ScSwQqXVTIfJcGA9UBM8yzQxhqg= -github.com/ossf/scorecard/v4 v4.8.1-0.20221113231904-ca55bd0e67ea h1:pX4GJ+yJhaiOdXf+JRaC8C4sIDR1xJxvfvu8bBddjzM= -github.com/ossf/scorecard/v4 v4.8.1-0.20221113231904-ca55bd0e67ea/go.mod h1:yz0RqjuKHzH6wxwRGzaolnimIFAk/38qVgLg2l7kdig= +github.com/ossf/scorecard/v4 v4.8.1-0.20221116210408-a78b27d14e74 h1:ndtzk/dcL095+Z6AfUX9mwDUf8TXIgerIzQweo3iqao= +github.com/ossf/scorecard/v4 v4.8.1-0.20221116210408-a78b27d14e74/go.mod h1:y7fSEI/MYuvcZDaqBi5q74AmOudqEgv0hOnECRnf8oc= github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4/go.mod h1:4OwLy04Bl9Ef3GJJCoec+30X3LQs/0/m4HFRt/2LUSA= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -587,6 +587,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= +golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= diff --git a/go.work.sum b/go.work.sum index 50913982..64afe24c 100644 --- a/go.work.sum +++ b/go.work.sum @@ -57,33 +57,60 @@ cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuW cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= contrib.go.opencensus.io/exporter/stackdriver v0.13.11 h1:YzmWJ2OT2K3ouXyMm5FmFQPoDs5TfLjx6Xn5x5CLN0I= contrib.go.opencensus.io/exporter/stackdriver v0.13.13 h1:3KLhsPyyFp1pfZPicg8e1VMSeztIyWm+aE+iZQ8b9Kg= +github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= +github.com/Azure/go-autorest/autorest v0.11.22 h1:bXiQwDjrRmBQOE67bwlvUKAC1EU1yZTPQ38c+bstZws= +github.com/Azure/go-autorest/autorest/adal v0.9.17 h1:esOPl2dhcz9P3jqBSJ8tPGEj2EqzPPT6zfyuloiogKY= +github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= +github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= github.com/caarlos0/env/v6 v6.9.1 h1:zOkkjM0F6ltnQ5eBX6IPI41UP/KDGEK7rRPwGCNos8k= +github.com/caarlos0/env/v6 v6.10.0 h1:lA7sxiGArZ2KkiqpOQNf8ERBRWI+v8MWIH+eGjSN22I= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= +github.com/containerd/stargz-snapshotter/estargz v0.12.1 h1:+7nYmHJb0tEkcRaAW+MHqoKaJYZmkikupxCqVtmPuY0= +github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= +github.com/docker/cli v20.10.20+incompatible h1:lWQbHSHUFs7KraSN2jOJK7zbMS2jNCHI4mt4xUFUVQ4= +github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= +github.com/docker/docker v20.10.20+incompatible h1:kH9tx6XO+359d+iAkumyKDc5Q1kOwPuAUaeri48nD6E= +github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/google/go-containerregistry v0.12.1 h1:W1mzdNUTx4Zla4JaixCRLhORcR7G6KxE5hHl5fkPsp8= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= +github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jszwec/csvutil v1.6.0 h1:QORXquCT0t8nUKD7utAD4HDmQMgG0Ir9WieZXzpa7ms= +github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= +github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/moby/buildkit v0.8.3 h1:vFlwUQ6BZE1loZ8zoZH3fYgmA1djFCS3DrOhCVU6ZZE= +github.com/moby/buildkit v0.10.3 h1:/dGykD8FW+H4p++q5+KqKEo6gAkYKyBQHdawdjVwVAU= +github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= +github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= github.com/rhysd/actionlint v1.6.11 h1:8aD7ozc43RbnKwUmFvRtfW0LTW6f13MTXFDlf+0PNAc= +github.com/rhysd/actionlint v1.6.15 h1:IxQIp10aVce77jNnoHye7NFka8/7CRBSvKXoMRGryXM= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f h1:mvXjJIHRZyhNuGassLTcXTwjiWq7NmjdavZsUnmFybQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= -golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= -golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= @@ -116,4 +143,7 @@ google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= +gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= mvdan.cc/sh/v3 v3.4.3 h1:zbuKH7YH9cqU6PGajhFFXZY7dhPXcDr55iN/cUAqpuw= +mvdan.cc/sh/v3 v3.5.1 h1:hmP3UOw4f+EYexsJjFxvU38+kn+V/s2CclXHanIBkmQ= +sigs.k8s.io/release-utils v0.6.0 h1:wJDuzWJqPH4a5FAxAXE2aBvbB6UMIW7iYMhsKnIMQkA= diff --git a/infra/cloudbuild/csv_transfer/cloudbuild.yaml b/infra/cloudbuild/csv_transfer/cloudbuild.yaml new file mode 100644 index 00000000..ed802aec --- /dev/null +++ b/infra/cloudbuild/csv_transfer/cloudbuild.yaml @@ -0,0 +1,22 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +steps: +- name: 'gcr.io/cloud-builders/docker' + args: ['build', '.', + '--build-arg', 'COMMIT_SHA=$COMMIT_SHA', + '-t', 'gcr.io/openssf/criticality-score-csv-transfer:$COMMIT_SHA', + '-t', 'gcr.io/openssf/criticality-score-csv-transfer:latest', + '-f', 'cmd/csv_transfer/Dockerfile'] +images: ['gcr.io/openssf/criticality-score-csv-transfer'] diff --git a/infra/config.yaml b/infra/config.yaml index f7149747..ef75b7f6 100644 --- a/infra/config.yaml +++ b/infra/config.yaml @@ -36,7 +36,11 @@ additional-params: scoring: enabled scoring-config: config/scorer/pike_depsdev.yml scoring-column-name: default_score - output-format: json + csv-transfer-bucket-url: gs://ossf-criticality-score + csv-transfer-filename: all.csv scorecard: - # Unused, but must be present to prevent errors. + # Use the raw-result-data-bucket-url in place of a better option. + # The controller will write the shard metadata to this bucket. + # TODO: use a more sensible configuration entry + raw-result-data-bucket-url: gs://ossf-criticality-score-csv-data diff --git a/infra/k8s/csv_transfer.yaml b/infra/k8s/csv_transfer.yaml new file mode 100644 index 00000000..9b196efd --- /dev/null +++ b/infra/k8s/csv_transfer.yaml @@ -0,0 +1,45 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: criticality-score-csv-transfer +spec: + # At 02:00UTC on the 28th day of the month. + schedule: "0 2 28 * *" + concurrencyPolicy: "Forbid" + jobTemplate: + spec: + template: + spec: + containers: + - name: bq-transfer + image: gcr.io/openssf/criticality-score-csv-transfer:latest + args: ["--config=/etc/criticality_score/config.yaml"] + imagePullPolicy: Always + resources: + limits: + memory: 5Gi + requests: + memory: 2Gi + volumeMounts: + - name: config-volume + mountPath: /etc/criticality_score + readOnly: true + volumes: + - name: config-volume + configMap: + name: criticality-score-config + restartPolicy: OnFailure diff --git a/internal/log/config.go b/internal/log/config.go index f5157ab1..cfa33c8d 100644 --- a/internal/log/config.go +++ b/internal/log/config.go @@ -6,6 +6,11 @@ import ( "go.uber.org/zap/zapcore" ) +const ( + configLogEnvKey = "log-env" + configLogLevelKey = "log-level" +) + func dev() (zap.Config, []zap.Option) { c := zap.NewDevelopmentConfig() c.EncoderConfig.CallerKey = zapcore.OmitKey @@ -24,6 +29,11 @@ func gcp() (zap.Config, []zap.Option) { return c, []zap.Option{zapdriver.WrapCore()} } +// NewLogger returns a new instance of the zap.Logger based on the specified +// env and level. +// +// The level sets the minimum level log messages will be output, with +// env being used to configure the logger for a particular environment. func NewLogger(e Env, l zapcore.Level) (*zap.Logger, error) { var c zap.Config var opts []zap.Option @@ -37,3 +47,28 @@ func NewLogger(e Env, l zapcore.Level) (*zap.Logger, error) { c.Level = zap.NewAtomicLevelAt(l) return c.Build(opts...) } + +// NewLoggerFromConfigMap returns a new instance of the zap.Logger based on +// the value of the keys "log-env" and "log-level" in the config map. +// +// If the "log-env" key is not present, defaultEnv will be used. +// If the "log-level" key is not present, defaultLevel will be used. +func NewLoggerFromConfigMap(defaultEnv Env, defaultLevel zapcore.Level, config map[string]string) (*zap.Logger, error) { + // Extract the log environment from the config, if it exists. + logEnv := defaultEnv + if val := config[configLogEnvKey]; val != "" { + if err := logEnv.UnmarshalText([]byte(val)); err != nil { + return nil, err + } + } + + // Extract the log level from the config, if it exists. + logLevel := defaultLevel + if val := config[configLogLevelKey]; val != "" { + if err := logLevel.Set(val); err != nil { + return nil, err + } + } + + return NewLogger(logEnv, logLevel) +} From 79716ff419aeeb0bf355a450f0a9fb6f72fb86c4 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Wed, 23 Nov 2022 16:33:01 -0600 Subject: [PATCH 134/172] Included tests for scorer/config (#247) * Included tests for scorer/config - Included tests for ToAlgorithmInput(), LoadConfig(), and some for buildCondition() - Couldn't test other functions because they returned functions, and they couldn't be compared. Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated based on code review comments. Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Changed based on review Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed imports Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed linter issues Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated go.work.sum Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- .gitignore | 5 +- internal/scorer/config_test.go | 227 +++++++++++++++++++ internal/scorer/testdata/default_config.yml | 21 ++ internal/scorer/testdata/invalid_config.yaml | 22 ++ 4 files changed, 274 insertions(+), 1 deletion(-) create mode 100644 internal/scorer/config_test.go create mode 100644 internal/scorer/testdata/default_config.yml create mode 100644 internal/scorer/testdata/invalid_config.yaml diff --git a/.gitignore b/.gitignore index b83972c3..c0f94200 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,7 @@ __pycache__/ .ropeproject # Installing the package locally for development -*.egg-info \ No newline at end of file +*.egg-info + +# This is for IDEs/Editors +.idea \ No newline at end of file diff --git a/internal/scorer/config_test.go b/internal/scorer/config_test.go new file mode 100644 index 00000000..4a870555 --- /dev/null +++ b/internal/scorer/config_test.go @@ -0,0 +1,227 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package scorer + +import ( + "os" + "reflect" + "testing" + + "github.com/google/go-cmp/cmp" + + "github.com/ossf/criticality_score/internal/scorer/algorithm" +) + +func TestInput_ToAlgorithmInput(t *testing.T) { + type fields struct { + Bounds *algorithm.Bounds + Condition *Condition + Field string + Distribution string + Tags []string + Weight float64 + } + //nolint:govet + tests := []struct { + name string + fields fields + want *algorithm.Input + wantErr bool + }{ + { + name: "unknown distribution error", + fields: fields{ + Field: "test", + }, + want: &algorithm.Input{}, + wantErr: true, + }, + { + name: "distribution value set", + fields: fields{ + Field: "test", + Distribution: "linear", + }, + want: &algorithm.Input{ + Source: algorithm.Value(algorithm.Field("test")), + Distribution: algorithm.LookupDistribution("linear"), + }, + wantErr: false, + }, + { + name: "valid condition", + fields: fields{ + Field: "test", + Distribution: "linear", + Condition: &Condition{ + FieldExists: "test", + }, + }, + want: &algorithm.Input{ + Distribution: algorithm.LookupDistribution("linear"), + }, + wantErr: false, + }, + { + name: "invalid condition", + fields: fields{ + Field: "test", + Distribution: "linear", + Condition: &Condition{ + FieldExists: "test", + Not: &Condition{ + FieldExists: "test", + }, + }, + }, + want: &algorithm.Input{}, + wantErr: true, + }, + } + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + i := &Input{ + Bounds: test.fields.Bounds, + Condition: test.fields.Condition, + Field: test.fields.Field, + Distribution: test.fields.Distribution, + Tags: test.fields.Tags, + Weight: test.fields.Weight, + } + got, err := i.ToAlgorithmInput() + if (err != nil) != test.wantErr { + t.Fatalf("ToAlgorithmInput() error = %v, wantErr %v", err, test.wantErr) + } + if test.wantErr { + return + } + + // Comparing specific fields independently because some of the structs have a func as a field which + // can't be used for comparison with reflect.DeepEqual() + + if got.Distribution.String() != test.want.Distribution.String() { + t.Errorf("ToAlgorithmInput() got = %v, want %v", got, test.want) + } + if got.Bounds != test.want.Bounds { + t.Errorf("ToAlgorithmInput() got = %v, want %v", got, test.want) + } + if got.Weight != test.want.Weight { + t.Errorf("ToAlgorithmInput() got = %v, want %v", got, test.want) + } + if !reflect.DeepEqual(got.Tags, test.want.Tags) { + t.Errorf("ToAlgorithmInput() got = %v, want %v", got, test.want) + } + }) + } +} + +func TestLoadConfig(t *testing.T) { + type args struct { + r string + } + //nolint:govet + tests := []struct { + name string + args args + want *Config + wantErr bool + }{ + { + name: "valid config", + args: args{ + r: "testdata/default_config.yml", + }, + want: &Config{ + Name: "test", + Inputs: []*Input{ + { + Field: "test", + Distribution: "linear", + Weight: 1, + }, + }, + }, + }, + { + name: "invalid yaml", + args: args{ + r: "testdata/invalid_config.yaml", + }, + want: &Config{}, + wantErr: true, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // read file + + f, err := os.Open(tt.args.r) + if err != nil { + t.Errorf("LoadConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + + got, err := LoadConfig(f) + if (err != nil) != tt.wantErr { + t.Errorf("LoadConfig() error = %v, wantErr %v", err, tt.wantErr) + return + } + + if tt.wantErr { + return + } + + if !cmp.Equal(got.Inputs, tt.want.Inputs) || got.Name != tt.want.Name { + t.Log(cmp.Diff(got.Inputs, tt.want.Inputs)) + t.Errorf("LoadConfig() got = %v, want %v", got, tt.want) + } + }) + } +} + +func Test_buildCondition(t *testing.T) { + type args struct { + c *Condition + } + //nolint:govet + tests := []struct { + name string + args args + want algorithm.Condition + wantErr bool + }{ + { + name: "invalid condition", + args: args{ + c: &Condition{}, + }, + want: nil, + wantErr: true, + }, + + // Can't test the c.Not condition because algorithm.Condition is a func and can't be compared + } + test := tests[0] + got, err := buildCondition(test.args.c) + + if (err != nil) != test.wantErr { + t.Errorf("buildCondition() error = %v, wantErr %v", err, test.wantErr) + return + } + if !reflect.DeepEqual(got, test.want) { + t.Errorf("buildCondition() got = %v, want %v", got, test.want) + } +} diff --git a/internal/scorer/testdata/default_config.yml b/internal/scorer/testdata/default_config.yml new file mode 100644 index 00000000..a82bc7d1 --- /dev/null +++ b/internal/scorer/testdata/default_config.yml @@ -0,0 +1,21 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +# Test Data + +algorithm: test + +inputs: + - field: test + distribution: linear \ No newline at end of file diff --git a/internal/scorer/testdata/invalid_config.yaml b/internal/scorer/testdata/invalid_config.yaml new file mode 100644 index 00000000..4ef31df1 --- /dev/null +++ b/internal/scorer/testdata/invalid_config.yaml @@ -0,0 +1,22 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +# Test Data + +This shouldn't work + algorithm: test + inputs: +- field: test + distribution: + linear \ No newline at end of file From c4797c72f4688e6bdcdc812274b273048ca04aba Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 24 Nov 2022 13:53:45 +1100 Subject: [PATCH 135/172] Build a more formal deploy process and improve infra config (#250) * Implement a concrete deploy process for criticality score. Signed-off-by: Caleb Brown --- .gcloudignore | 9 ++ .github/workflows/ci.yml | 2 + .gitignore | 9 +- Makefile | 8 +- infra/README.md | 92 ++++++++++++++++++ infra/cloudbuild/release.yaml | 36 +++++++ infra/clouddeploy.yaml | 48 ++++++++++ infra/{k8s => envs/base}/auth.yaml | 6 +- .../base/bq_transfer.yaml} | 2 +- infra/{k8s => envs/base}/controller.yaml | 35 +------ infra/{k8s => envs/base}/csv_transfer.yaml | 2 +- infra/envs/base/kustomization.yaml | 47 +++++++++ infra/{k8s => envs/base}/worker.yaml | 4 +- infra/{ => envs/prod}/config.yaml | 0 infra/envs/prod/kustomization.yaml | 27 ++++++ infra/envs/staging/auth_secret_key.yaml | 29 ++++++ infra/envs/staging/bq_transfer_schedule.yaml | 21 ++++ infra/envs/staging/config.yaml | 46 +++++++++ infra/envs/staging/controller_schedule.yaml | 21 ++++ infra/envs/staging/csv_transfer_schedule.yaml | 21 ++++ infra/envs/staging/kustomization.yaml | 36 +++++++ infra/envs/staging/worker_replicas.yaml | 20 ++++ infra/skaffold.yaml | 31 ++++++ scripts/validate-scorecard-version.sh | 96 +++++++++++++++++++ 24 files changed, 604 insertions(+), 44 deletions(-) create mode 100644 .gcloudignore create mode 100644 infra/README.md create mode 100644 infra/cloudbuild/release.yaml create mode 100644 infra/clouddeploy.yaml rename infra/{k8s => envs/base}/auth.yaml (90%) rename infra/{k8s/transfer.yaml => envs/base/bq_transfer.yaml} (95%) rename infra/{k8s => envs/base}/controller.yaml (59%) rename infra/{k8s => envs/base}/csv_transfer.yaml (95%) create mode 100644 infra/envs/base/kustomization.yaml rename infra/{k8s => envs/base}/worker.yaml (92%) rename infra/{ => envs/prod}/config.yaml (100%) create mode 100644 infra/envs/prod/kustomization.yaml create mode 100644 infra/envs/staging/auth_secret_key.yaml create mode 100644 infra/envs/staging/bq_transfer_schedule.yaml create mode 100644 infra/envs/staging/config.yaml create mode 100644 infra/envs/staging/controller_schedule.yaml create mode 100644 infra/envs/staging/csv_transfer_schedule.yaml create mode 100644 infra/envs/staging/kustomization.yaml create mode 100644 infra/envs/staging/worker_replicas.yaml create mode 100644 infra/skaffold.yaml create mode 100644 scripts/validate-scorecard-version.sh diff --git a/.gcloudignore b/.gcloudignore new file mode 100644 index 00000000..131fba38 --- /dev/null +++ b/.gcloudignore @@ -0,0 +1,9 @@ +.git +.github +docs +images +*.md +*.pdf +*.py + +#!include:.gitignore \ No newline at end of file diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5e3be560..18061cf3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,6 +18,8 @@ jobs: go-version: 1.19 - name: Run tests run: make test + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} run-linter: runs-on: ubuntu-latest steps: diff --git a/.gitignore b/.gitignore index c0f94200..e752351d 100644 --- a/.gitignore +++ b/.gitignore @@ -8,4 +8,11 @@ __pycache__/ *.egg-info # This is for IDEs/Editors -.idea \ No newline at end of file +.idea + +# Skaffold dir +.kpt-* +.swp + +# Test output +unit-coverage.out diff --git a/Makefile b/Makefile index 2c73abf7..98d670da 100644 --- a/Makefile +++ b/Makefile @@ -23,9 +23,13 @@ help: ## Display this help { printf " \033[36m%-25s\033[0m %s\n", $$1, $$2 } \ /^##@/ { printf "\n\033[1m%s\033[0m\n", substr($$0, 5) } ' $(MAKEFILE_LIST) -.PHONY: test -test: ## Run all tests +test-targets = test/unit test/scorecard-version +.PHONY: test $(test-targets) +test: $(test-targets) ## Run all tests +test/unit: go test -race -covermode=atomic -coverprofile=unit-coverage.out './...' +test/scorecard-version: + bash ./scripts/validate-scorecard-version.sh .PHONY: lint $(GOLANGCI_LINT): install/deps diff --git a/infra/README.md b/infra/README.md new file mode 100644 index 00000000..1a404fce --- /dev/null +++ b/infra/README.md @@ -0,0 +1,92 @@ +# Infrastructure + +This directory contains various infrastructure related components. + +## Contents + +- **cloudbuild**: various Google Cloud Build configurations for automated + building container images and kicking off new releases in Google Cloud Deploy. +- **envs**: Kubernetes and Kustomize based configurations for staging and prod + environments. + - **base**: shared configuration for prod and staging + - **prod**: production specific configuration + - **staging**: staging specific configuration +- **k8s**: Misc Kubernetes configurations for Pods that live outside the staging + and prod environments. +- **test**: A Docker Compose version of the infrastructure for local testing and + validation. +- **clouddeploy.yaml**, **skaffold.yaml**: Google Cloud Deploy configuration for + managing the release process of the Criticality Score infrastructure. + +## Deploy Process + +1. When a new commit is made to `main` (e.g. merged PR): + - `collect-signals` container image is built and pushed. + - `csv-transfer` container image is built and pushed. + - `enumerate-github` container image is built and pushed. +1. Every weekday a scheduled trigger starts a Google Cloud Build process (see + [release.yaml](https://github.com/ossf/criticality_score/blob/main/infra/cloudbuild/release.yaml)). + 1. `collect-signals` and `csv-transfer` container images are pulled for the + current commit SHA, ensuring the container images are present. + 1. A new Cloud Deploy release is created (if it doesn't exist already). + - Release named: `rel-${SHORT_SHA}`. + - Images are tagged with `${$COMMIT_SHA}` and used in the release. + - Scorecard images are hardcoded to match go.mod. +1. Cloud Deploy automatically releases to the + [staging environment](https://github.com/ossf/criticality_score/blob/main/infra/envs/staging). + - The staging environment runs a short run each weekday. +1. Once a staging release is confirmed as working, the release can be promoted + to the [production environment](https://github.com/ossf/criticality_score/blob/main/infra/envs/prod). + - Ideally this should be done between executions to avoid version skew + issues. + +## Cheat Sheet + +### Skaffold and Kustomize Output Inspection + +To inspect the expanded Kubernetes configuration for each environment use the +following commands, replacing the environment with the relevant one. + +For Kustomize (fast): + +```shell +kubectl kustomize ./infra/envs/{staging,prod} +``` + +For Skaffold (must be run from repo root): + +```shell +skaffold render -f ./infra/skaffold.yaml --offline -p {staging,prod} +``` + +### Kubernetes Information + +Connecting to the cluster with `gcloud` + +```shell +gcloud container clusters get-credentials --region us-central1-c criticality-score +``` + +Verify context: + +```shell +kubectl config current-context +``` + +#### Managing Secrets + +Updating Production GitHub access tokens: + +```shell +kubectl create secret generic github --from-literal=token=$GITHUB_AUTH_TOKENS +``` + +Updating Staging GitHub access tokens: + +```shell +kubectl create secret generic github_staging --from-literal=token=$GITHUB_AUTH_TOKENS +``` + +**Note:** `github` and `github_staging` must be disjoint sets of GitHub +personal access tokens. If they share tokens one environment may starve the +other. diff --git a/infra/cloudbuild/release.yaml b/infra/cloudbuild/release.yaml new file mode 100644 index 00000000..e320e764 --- /dev/null +++ b/infra/cloudbuild/release.yaml @@ -0,0 +1,36 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +steps: + +# Ensure criticality-score-collect-signals docker image already exists. +- name: 'gcr.io/cloud-builders/docker' + args: ['pull', 'gcr.io/openssf/criticality-score-collect-signals:$COMMIT_SHA'] + +# Ensure criticality-score-csv-transfer docker image already exists. +- name: 'gcr.io/cloud-builders/docker' + args: ['pull', 'gcr.io/openssf/criticality-score-csv-transfer:$COMMIT_SHA'] + +# Start a Cloud Deploy replease +- name: gcr.io/google.com/cloudsdktool/cloud-sdk + entrypoint: gcloud + args: + [ + "deploy", "releases", "create", "rel-${SHORT_SHA}", + "--delivery-pipeline", "criticality-score-deploy", + "--region", "us-central1", + "--annotations", "commitId=${REVISION_ID}", + "--skaffold-file=./infra/skaffold.yaml", + "--images", "collect-signals=gcr.io/openssf/criticality-score-collect-signals:$COMMIT_SHA,csv-transfer=gcr.io/openssf/criticality-score-csv-transfer:$COMMIT_SHA" + ] diff --git a/infra/clouddeploy.yaml b/infra/clouddeploy.yaml new file mode 100644 index 00000000..cae15a7e --- /dev/null +++ b/infra/clouddeploy.yaml @@ -0,0 +1,48 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: deploy.cloud.google.com/v1beta1 +kind: DeliveryPipeline +metadata: + name: criticality-score-deploy +description: Pipeline for deploying Criticality Score +serialPipeline: + stages: + - targetId: stagingTarget + profiles: + - staging + - targetId: prodTarget + profiles: + - prod + +--- + +apiVersion: deploy.cloud.google.com/v1beta1 +kind: Target +metadata: + name: stagingTarget +description: Staging deploy target +gke: + cluster: projects/openssf/locations/us-central1-c/clusters/criticality-score + +--- + +apiVersion: deploy.cloud.google.com/v1beta1 +kind: Target +metadata: + name: prodTarget +description: Production deploy target +gke: + cluster: projects/openssf/locations/us-central1-c/clusters/criticality-score +requireApproval: true diff --git a/infra/k8s/auth.yaml b/infra/envs/base/auth.yaml similarity index 90% rename from infra/k8s/auth.yaml rename to infra/envs/base/auth.yaml index a94216d6..04c8e76a 100644 --- a/infra/k8s/auth.yaml +++ b/infra/envs/base/auth.yaml @@ -15,7 +15,7 @@ apiVersion: v1 kind: Service metadata: - name: criticality-score-github-service + name: criticality-score-github-auth spec: selector: app.kubernetes.io/name: github-auth-server @@ -29,7 +29,7 @@ spec: apiVersion: apps/v1 kind: Deployment metadata: - name: criticality-score-github-server + name: criticality-score-github-auth spec: replicas: 1 selector: @@ -42,7 +42,7 @@ spec: spec: containers: - name: github-auth-server - image: gcr.io/openssf/scorecard-github-server:stable + image: scorecard-github-server imagePullPolicy: Always env: - name: GITHUB_AUTH_TOKEN diff --git a/infra/k8s/transfer.yaml b/infra/envs/base/bq_transfer.yaml similarity index 95% rename from infra/k8s/transfer.yaml rename to infra/envs/base/bq_transfer.yaml index 76e61546..b61b2f1b 100644 --- a/infra/k8s/transfer.yaml +++ b/infra/envs/base/bq_transfer.yaml @@ -26,7 +26,7 @@ spec: spec: containers: - name: bq-transfer - image: gcr.io/openssf/scorecard-bq-transfer:latest + image: scorecard-bq-transfer args: ["--config=/etc/criticality_score/config.yaml"] imagePullPolicy: Always resources: diff --git a/infra/k8s/controller.yaml b/infra/envs/base/controller.yaml similarity index 59% rename from infra/k8s/controller.yaml rename to infra/envs/base/controller.yaml index cfeb5031..026b622c 100644 --- a/infra/k8s/controller.yaml +++ b/infra/envs/base/controller.yaml @@ -12,32 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -# This role is used to administer the batch-worker. -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: criticality-score-batch-controller -rules: - - apiGroups: ["apps", "extensions"] - resources: ["deployments"] - resourceNames: ["criticality-score-batch-worker"] - verbs: ["get", "patch"] ---- - -# Bind the role above to the controller, so it can restart the batch-worker. -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: criticality-score-batch-controller -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: criticality-score-batch-controller -subjects: - - kind: ServiceAccount - name: default ---- - apiVersion: batch/v1 kind: CronJob metadata: @@ -53,7 +27,7 @@ spec: restartPolicy: Never containers: - name: controller - image: gcr.io/openssf/scorecard-batch-controller:latest + image: scorecard-batch-controller args: ["--config=/etc/criticality_score/config.yaml"] imagePullPolicy: Always env: @@ -68,13 +42,6 @@ spec: - name: config-volume mountPath: /etc/criticality_score readOnly: true - - name: worker-update - image: bitnami/kubectl@sha256:44468c0f5b348e6dcf5e11feb6fdcc969c874bba2856150fe50eb1aacb3bdfee - command: - - "kubectl" - - "rollout" - - "restart" - - "deployment/criticality-score-batch-worker" volumes: - name: config-volume configMap: diff --git a/infra/k8s/csv_transfer.yaml b/infra/envs/base/csv_transfer.yaml similarity index 95% rename from infra/k8s/csv_transfer.yaml rename to infra/envs/base/csv_transfer.yaml index 9b196efd..eaf66c41 100644 --- a/infra/k8s/csv_transfer.yaml +++ b/infra/envs/base/csv_transfer.yaml @@ -26,7 +26,7 @@ spec: spec: containers: - name: bq-transfer - image: gcr.io/openssf/criticality-score-csv-transfer:latest + image: csv-transfer args: ["--config=/etc/criticality_score/config.yaml"] imagePullPolicy: Always resources: diff --git a/infra/envs/base/kustomization.yaml b/infra/envs/base/kustomization.yaml new file mode 100644 index 00000000..abf92c84 --- /dev/null +++ b/infra/envs/base/kustomization.yaml @@ -0,0 +1,47 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +resources: +- auth.yaml +- bq_transfer.yaml +- controller.yaml +- csv_transfer.yaml +- worker.yaml + +# Dummy config map to ensure the label below is applied. +configMapGenerator: +- name: criticality-score-config + +# Add an identifying label to allow pruning of unused resources (i.e. ConfigMaps). +commonLabels: + managed-by-kustomize: "true" + +# Hardcode versions to match go.mod for github.com/ossf/scorecard. +images: +- name: scorecard-batch-controller + newName: gcr.io/openssf/scorecard-batch-controller + newTag: a78b27d14e741ac1f541ce12bb71a7c60426cb6a +- name: scorecard-github-server + newName: gcr.io/openssf/scorecard-github-server + newTag: a78b27d14e741ac1f541ce12bb71a7c60426cb6a +- name: scorecard-bq-transfer + newName: gcr.io/openssf/scorecard-bq-transfer + newTag: a78b27d14e741ac1f541ce12bb71a7c60426cb6a + +vars: +- name: GITHUB_AUTH_SERVER + objref: + kind: Service + name: criticality-score-github-auth + apiVersion: v1 diff --git a/infra/k8s/worker.yaml b/infra/envs/base/worker.yaml similarity index 92% rename from infra/k8s/worker.yaml rename to infra/envs/base/worker.yaml index d3427be5..2bab1426 100644 --- a/infra/k8s/worker.yaml +++ b/infra/envs/base/worker.yaml @@ -28,12 +28,12 @@ spec: spec: containers: - name: worker - image: gcr.io/openssf/criticality-score-collect-signals:latest + image: collect-signals args: ["--config=/etc/criticality_score/config.yaml"] imagePullPolicy: Always env: - name: GITHUB_AUTH_SERVER - value: "criticality-score-github-service:80" + value: "$(GITHUB_AUTH_SERVER):80" resources: requests: memory: 5Gi diff --git a/infra/config.yaml b/infra/envs/prod/config.yaml similarity index 100% rename from infra/config.yaml rename to infra/envs/prod/config.yaml diff --git a/infra/envs/prod/kustomization.yaml b/infra/envs/prod/kustomization.yaml new file mode 100644 index 00000000..c771ef6a --- /dev/null +++ b/infra/envs/prod/kustomization.yaml @@ -0,0 +1,27 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +bases: +- ../base + +# Add identifying labels for the prod environment. +commonLabels: + env: prod + +# Use a staging specific configuration file. +configMapGenerator: +- name: criticality-score-config + behavior: replace + files: + - config.yaml diff --git a/infra/envs/staging/auth_secret_key.yaml b/infra/envs/staging/auth_secret_key.yaml new file mode 100644 index 00000000..bd766f75 --- /dev/null +++ b/infra/envs/staging/auth_secret_key.yaml @@ -0,0 +1,29 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: criticality-score-github-auth +spec: + template: + spec: + containers: + - name: github-auth-server + env: + - name: GITHUB_AUTH_TOKEN + valueFrom: + secretKeyRef: + name: github_staging + key: token diff --git a/infra/envs/staging/bq_transfer_schedule.yaml b/infra/envs/staging/bq_transfer_schedule.yaml new file mode 100644 index 00000000..ea768bde --- /dev/null +++ b/infra/envs/staging/bq_transfer_schedule.yaml @@ -0,0 +1,21 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: criticality-score-bq-transfer +spec: + # At 12:00UTC each weekday. + schedule: "0 12 * * 1-5" diff --git a/infra/envs/staging/config.yaml b/infra/envs/staging/config.yaml new file mode 100644 index 00000000..04ba1a66 --- /dev/null +++ b/infra/envs/staging/config.yaml @@ -0,0 +1,46 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +project-id: openssf +request-topic-url: gcppubsub://projects/openssf/topics/criticality-score-batch-requests-staging +request-subscription-url: gcppubsub://projects/openssf/subscriptions/criticality-score-batch-worker-staging +bigquery-dataset: criticality_score_cron +bigquery-table: criticality-score-v0-staging +completion-threshold: 0.99 +shard-size: 10 +webhook-url: +metric-exporter: stackdriver +metric-stackdriver-prefix: criticality-score-cron-staging +result-data-bucket-url: gs://ossf-criticality-score-data-staging + +additional-params: + input-bucket: + url: gs://ossf-criticality-score-url-data-staging + prefix-file: latest + + criticality: + log-env: gcp + log-level: info + dataset: ossf_criticality_score_depsdev_staging + scoring: enabled + scoring-config: config/scorer/pike_depsdev.yml + scoring-column-name: default_score + csv-transfer-bucket-url: gs://ossf-criticality-score-staging + csv-transfer-filename: all.csv + + scorecard: + # Use the raw-result-data-bucket-url in place of a better option. + # The controller will write the shard metadata to this bucket. + # TODO: use a more sensible configuration entry + raw-result-data-bucket-url: gs://ossf-criticality-score-csv-data-staging diff --git a/infra/envs/staging/controller_schedule.yaml b/infra/envs/staging/controller_schedule.yaml new file mode 100644 index 00000000..b04fc768 --- /dev/null +++ b/infra/envs/staging/controller_schedule.yaml @@ -0,0 +1,21 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: criticality-score-batch-controller +spec: + # At 02:00UTC each weekday. + schedule: "0 2 * * 1-5" diff --git a/infra/envs/staging/csv_transfer_schedule.yaml b/infra/envs/staging/csv_transfer_schedule.yaml new file mode 100644 index 00000000..e36c215c --- /dev/null +++ b/infra/envs/staging/csv_transfer_schedule.yaml @@ -0,0 +1,21 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: batch/v1 +kind: CronJob +metadata: + name: criticality-score-csv-transfer +spec: + # At 12:00UTC each weekday. + schedule: "0 12 * * 1-5" diff --git a/infra/envs/staging/kustomization.yaml b/infra/envs/staging/kustomization.yaml new file mode 100644 index 00000000..000a098a --- /dev/null +++ b/infra/envs/staging/kustomization.yaml @@ -0,0 +1,36 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +bases: +- ../base + +# Add identifying labels for the staging environment. +nameSuffix: -staging +commonLabels: + env: staging + +# Use a staging specific configuration file. +configMapGenerator: +- name: criticality-score-config + behavior: replace + files: + - config.yaml + +# Patches customize the base configurations for the staging environment. +patchesStrategicMerge: +- auth_secret_key.yaml +- worker_replicas.yaml +- controller_schedule.yaml +- csv_transfer_schedule.yaml +- bq_transfer_schedule.yaml diff --git a/infra/envs/staging/worker_replicas.yaml b/infra/envs/staging/worker_replicas.yaml new file mode 100644 index 00000000..3298aee6 --- /dev/null +++ b/infra/envs/staging/worker_replicas.yaml @@ -0,0 +1,20 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: criticality-score-batch-worker +spec: + replicas: 4 diff --git a/infra/skaffold.yaml b/infra/skaffold.yaml new file mode 100644 index 00000000..19a1db3a --- /dev/null +++ b/infra/skaffold.yaml @@ -0,0 +1,31 @@ +# Copyright 2022 Criticality Score 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 +# +# 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. + +apiVersion: skaffold/v2beta29 +kind: Config +profiles: + - name: staging + deploy: + kustomize: + paths: + - infra/envs/staging + flags: + apply: ['--prune', '-l', 'managed-by-kustomize="true"'] + - name: prod + deploy: + kustomize: + paths: + - infra/envs/prod + flags: + apply: ['--prune', '-l', 'managed-by-kustomize="true"'] diff --git a/scripts/validate-scorecard-version.sh b/scripts/validate-scorecard-version.sh new file mode 100644 index 00000000..9a402ef8 --- /dev/null +++ b/scripts/validate-scorecard-version.sh @@ -0,0 +1,96 @@ +#!/usr/bin/env bash +# Copyright 2022 Criticality Score 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 +# +# 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. + +# Validate that the commit assigned to the Go dependency of Scorecard matches +# the production Docker images used when running Criticality Score. +# +# This check ensures that there is no version skew against Scorecard. Since +# our code depends on the behavior of various Scorecard cron libraries it is +# important that the production images built by the Scorecard project remain +# consistent. +# +# In particular the way config.yaml files are parsed, messages are passed +# between the controller and worker, or the shard file structure, may change in +# ways that break Criticality Score if the versions are not kept in sync. + +# Get the path to the GitHub CLI. THis should be available in the GitHub Action Images. +GH_BIN=$(which gh) +if [ "$GH_BIN" = "" ]; then + echo "Failed to find GitHub CLI." + exit 1 +fi + +# The location of the kustomization file with the Scorecard image tags. +KUSTOMIZATION_FILE=infra/envs/base/kustomization.yaml + +# The location of the go.mod file with the ossf/scorecard dependency. +GO_MOD=go.mod + +KUSTOMIZATION_KEY="newTag:" +SCORECARD_REPO="ossf/scorecard" +SCORECARD_PATTERN="github.com/$SCORECARD_REPO" + +# Get image tags from the kustomization file +IMAGE_TAGS=$(grep "$KUSTOMIZATION_KEY" "$KUSTOMIZATION_FILE" | sort | uniq | sed "s/^\s*$KUSTOMIZATION_KEY\s*//") + +# Get the version from the go.mod file +SCORECARD_VERSION=$(grep "$SCORECARD_PATTERN" "$GO_MOD" | cut -d' ' -f2) +if [ "$SCORECARD_VERSION" = "" ]; then + echo "Scorecard dependency missing from $GO_MOD." + exit 1 +fi + +# Test 1: Ensure the same tag is used for each image. +TAG_COUNT=$(echo "$IMAGE_TAGS" | wc -l) +if [ "$TAG_COUNT" != "1" ]; then + echo "$KUSTOMIZATION_FILE: Scorecard image tags found: $TAG_COUNT. Want: 1" + exit 1 +fi + +# Test 2: Treat the Go version as a pre-release version. +SHORT_SHA=$(echo "$SCORECARD_VERSION" | sed -n 's|^.*-\([a-zA-Z0-9]*\)$|\1|p') +if [ "$SHORT_SHA" = "" ]; then + echo "Scorecard version does not contain a SHORT_SHA" +else + # Find the full commit sha from GitHub using the GitHub CLI + COMMIT_SHA=$($GH_BIN api "repos/$SCORECARD_REPO/commits/$SHORT_SHA" -q .sha) + if [ "$?" != "0" ]; then + : # Ignore error. Treat it like a tag. + elif [ "$COMMIT_SHA" = "$IMAGE_TAGS" ]; then + exit 0 + elif [ "$COMMIT_SHA" != "" ]; then + echo "$GO_MOD $COMMIT_SHA does not match $KUSTOMIZATION_FILE $IMAGE_TAGS" + exit 1 + fi + # If we reach here, then $COMMIT_SHA is empty. So it is possible that the + # $SCORECARD_VERSION is a tag. +fi + +# Test 3: Treat the Go version as a Git tag - turn it into a commit ID. +TAG_URL=$($GH_BIN api "repos/$SCORECARD_REPO/git/ref/tags/$SCORECARD_VERSION" -q .object.url) +if [ "$?" != "0" ]; then + echo "Failed to get data for $GO_MOD version $SCORECARD_VERSION" + exit 1 +fi +COMMIT_SHA=$($GH_BIN api "$TAG_URL" -q .object.sha) +if [ "$COMMIT_SHA" = "$IMAGE_TAGS" ]; then + exit 0 +elif [ "$COMMIT_SHA" != "" ]; then + echo "$GO_MOD $COMMIT_SHA does not match $KUSTOMIZATION_FILE $IMAGE_TAGS" + exit 1 +else + echo "No SHA found for $GO_MOD $SCORECARD_PATTERN @ $SCORECARD_VERSION" + exit 1 +fi From f5fede1916fbea527144c713f4c79f1ab191ba2b Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 24 Nov 2022 14:47:18 +1100 Subject: [PATCH 136/172] Can't have underscores in kubectl secrets. (#251) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- infra/README.md | 4 ++-- infra/envs/staging/auth_secret_key.yaml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/infra/README.md b/infra/README.md index 1a404fce..a0ca1f74 100644 --- a/infra/README.md +++ b/infra/README.md @@ -84,9 +84,9 @@ kubectl create secret generic github --from-literal=token=$GITHUB_AUTH_TOKENS Updating Staging GitHub access tokens: ```shell -kubectl create secret generic github_staging --from-literal=token=$GITHUB_AUTH_TOKENS +kubectl create secret generic github-staging --from-literal=token=$GITHUB_AUTH_TOKENS ``` -**Note:** `github` and `github_staging` must be disjoint sets of GitHub +**Note:** `github` and `github-staging` must be disjoint sets of GitHub personal access tokens. If they share tokens one environment may starve the other. diff --git a/infra/envs/staging/auth_secret_key.yaml b/infra/envs/staging/auth_secret_key.yaml index bd766f75..c3d974f6 100644 --- a/infra/envs/staging/auth_secret_key.yaml +++ b/infra/envs/staging/auth_secret_key.yaml @@ -25,5 +25,5 @@ spec: - name: GITHUB_AUTH_TOKEN valueFrom: secretKeyRef: - name: github_staging + name: github-staging key: token From bf51cd77f7119e0241e2d30279ff391b46d607a1 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 24 Nov 2022 15:26:33 +1100 Subject: [PATCH 137/172] Fix more Google Cloud name violations. (#252) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- infra/clouddeploy.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/infra/clouddeploy.yaml b/infra/clouddeploy.yaml index cae15a7e..ac000203 100644 --- a/infra/clouddeploy.yaml +++ b/infra/clouddeploy.yaml @@ -19,10 +19,10 @@ metadata: description: Pipeline for deploying Criticality Score serialPipeline: stages: - - targetId: stagingTarget + - targetId: staging-target profiles: - staging - - targetId: prodTarget + - targetId: prod-target profiles: - prod @@ -31,7 +31,7 @@ serialPipeline: apiVersion: deploy.cloud.google.com/v1beta1 kind: Target metadata: - name: stagingTarget + name: staging-target description: Staging deploy target gke: cluster: projects/openssf/locations/us-central1-c/clusters/criticality-score @@ -41,7 +41,7 @@ gke: apiVersion: deploy.cloud.google.com/v1beta1 kind: Target metadata: - name: prodTarget + name: prod-target description: Production deploy target gke: cluster: projects/openssf/locations/us-central1-c/clusters/criticality-score From f06643819ff38239b368f56f0f4f9e974ada32e9 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 24 Nov 2022 16:45:13 +1100 Subject: [PATCH 138/172] Fix some minor bugs with the deploy config. (#253) - Cloud Deploy and skaffold want paths relative to the config. - Unquote the value of the label so it parses correctly. Signed-off-by: Caleb Brown --- infra/README.md | 5 +++-- infra/skaffold.yaml | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/infra/README.md b/infra/README.md index a0ca1f74..5b511b97 100644 --- a/infra/README.md +++ b/infra/README.md @@ -53,10 +53,11 @@ For Kustomize (fast): kubectl kustomize ./infra/envs/{staging,prod} ``` -For Skaffold (must be run from repo root): +For Skaffold : ```shell -skaffold render -f ./infra/skaffold.yaml --offline -p {staging,prod} +cd infra && \ + skaffold render -f ./skaffold.yaml --offline -p {staging,prod} ``` ### Kubernetes Information diff --git a/infra/skaffold.yaml b/infra/skaffold.yaml index 19a1db3a..063fc05e 100644 --- a/infra/skaffold.yaml +++ b/infra/skaffold.yaml @@ -19,13 +19,13 @@ profiles: deploy: kustomize: paths: - - infra/envs/staging + - envs/staging flags: - apply: ['--prune', '-l', 'managed-by-kustomize="true"'] + apply: ['--prune', '-l', 'managed-by-kustomize=true'] - name: prod deploy: kustomize: paths: - - infra/envs/prod + - envs/prod flags: - apply: ['--prune', '-l', 'managed-by-kustomize="true"'] + apply: ['--prune', '-l', 'managed-by-kustomize=true'] From e8cd6b71813ee7bcf879edee9ca2515288122f0b Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 25 Nov 2022 13:27:50 +1100 Subject: [PATCH 139/172] Fix some more deploy issues. (#254) * Limit the prune to the specific environment. * Add a wait at the start of collect_signals for the auth server. --- cmd/collect_signals/main.go | 46 ++++++++++++++++++++++++++++++++++++- infra/skaffold.yaml | 4 ++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index 1090576d..db8d3d48 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -18,7 +18,10 @@ import ( "context" "flag" "net/http" + "net/rpc" + "os" "strings" + "time" "github.com/ossf/scorecard/v4/cron/config" "github.com/ossf/scorecard/v4/cron/worker" @@ -29,7 +32,44 @@ import ( log "github.com/ossf/criticality_score/internal/log" ) -const defaultLogLevel = zapcore.InfoLevel +const ( + defaultLogLevel = zapcore.InfoLevel + githubAuthServerMaxAttemps = 10 +) + +func waitForRPCServer(logger *zap.Logger, rpcServer string, maxAttempts int) { + if rpcServer == "" { + return + } + + logger = logger.With(zap.String("rpc_server", rpcServer)) + + retryWait := time.Second + attempt := 0 + for { + attempt++ + c, err := rpc.DialHTTP("tcp", rpcServer) + switch { + case err == nil: + c.Close() + logger.Info("GitHub auth server found.") + return + case attempt < maxAttempts: + logger.With( + zap.Error(err), + zap.Duration("wait", retryWait), + zap.Int("attempt", attempt), + ).Warn("Waiting for GitHub auth server.") + default: + // Fatal exits. + logger.With( + zap.Error(err), + ).Fatal("Unable to find GitHub auth server.") + } + time.Sleep(retryWait) + retryWait = retryWait + (retryWait / 2) + } +} func main() { flag.Parse() @@ -89,6 +129,10 @@ func main() { csvBucketURL = "" } + // The GitHub authentication server may be unavailable if it is starting + // at the same time. Wait until it can be reached. + waitForRPCServer(logger, os.Getenv("GITHUB_AUTH_SERVER"), githubAuthServerMaxAttemps) + // Bump the # idle conns per host http.DefaultTransport.(*http.Transport).MaxIdleConnsPerHost = 5 diff --git a/infra/skaffold.yaml b/infra/skaffold.yaml index 063fc05e..2289e0ac 100644 --- a/infra/skaffold.yaml +++ b/infra/skaffold.yaml @@ -21,11 +21,11 @@ profiles: paths: - envs/staging flags: - apply: ['--prune', '-l', 'managed-by-kustomize=true'] + apply: ['--prune', '-l', 'managed-by-kustomize=true,env=staging'] - name: prod deploy: kustomize: paths: - envs/prod flags: - apply: ['--prune', '-l', 'managed-by-kustomize=true'] + apply: ['--prune', '-l', 'managed-by-kustomize=true,env=prod'] From e2ee6f195528820a0d9dc8117d2e20f3a3fcfdd8 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 28 Nov 2022 10:41:41 +1100 Subject: [PATCH 140/172] Set the cron and make sure scheduled deploys don't spew errors. (#256) * Set the crons to more reasonable times. Signed-off-by: Caleb Brown * Allow failures so running deploys from cron to hide too many errors. Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- infra/cloudbuild/release.yaml | 4 +++- infra/envs/base/bq_transfer.yaml | 4 ++-- infra/envs/base/controller.yaml | 4 ++-- infra/envs/base/csv_transfer.yaml | 4 ++-- infra/envs/staging/bq_transfer_schedule.yaml | 4 ++-- infra/envs/staging/controller_schedule.yaml | 4 ++-- infra/envs/staging/csv_transfer_schedule.yaml | 4 ++-- 7 files changed, 15 insertions(+), 13 deletions(-) diff --git a/infra/cloudbuild/release.yaml b/infra/cloudbuild/release.yaml index e320e764..0437fee0 100644 --- a/infra/cloudbuild/release.yaml +++ b/infra/cloudbuild/release.yaml @@ -22,8 +22,10 @@ steps: - name: 'gcr.io/cloud-builders/docker' args: ['pull', 'gcr.io/openssf/criticality-score-csv-transfer:$COMMIT_SHA'] -# Start a Cloud Deploy replease +# Start a Cloud Deploy replease. Ignore failures as this will get run daily, +# even if latest commit hasn't changed. - name: gcr.io/google.com/cloudsdktool/cloud-sdk + allowFailure: true entrypoint: gcloud args: [ diff --git a/infra/envs/base/bq_transfer.yaml b/infra/envs/base/bq_transfer.yaml index b61b2f1b..98652bae 100644 --- a/infra/envs/base/bq_transfer.yaml +++ b/infra/envs/base/bq_transfer.yaml @@ -17,8 +17,8 @@ kind: CronJob metadata: name: criticality-score-bq-transfer spec: - # At 02:00UTC on the 28th day of the month. - schedule: "0 2 28 * *" + # At 3:00UTC, 13:00AEST on Wednesday and Friday. + schedule: "0 3 * * 3,5" concurrencyPolicy: "Forbid" jobTemplate: spec: diff --git a/infra/envs/base/controller.yaml b/infra/envs/base/controller.yaml index 026b622c..98a9302a 100644 --- a/infra/envs/base/controller.yaml +++ b/infra/envs/base/controller.yaml @@ -17,8 +17,8 @@ kind: CronJob metadata: name: criticality-score-batch-controller spec: - # At 02:00UTC on the first day of the Month. - schedule: "0 2 1 * *" + # At 23:00UTC on Sunday, or 9:00AEST on Monday. + schedule: "0 23 * * 0" concurrencyPolicy: "Forbid" jobTemplate: spec: diff --git a/infra/envs/base/csv_transfer.yaml b/infra/envs/base/csv_transfer.yaml index eaf66c41..1e1ee08e 100644 --- a/infra/envs/base/csv_transfer.yaml +++ b/infra/envs/base/csv_transfer.yaml @@ -17,8 +17,8 @@ kind: CronJob metadata: name: criticality-score-csv-transfer spec: - # At 02:00UTC on the 28th day of the month. - schedule: "0 2 28 * *" + # At 3:00UTC, 13:00AEST on Wednesday and Friday. + schedule: "0 3 * * 3,5" concurrencyPolicy: "Forbid" jobTemplate: spec: diff --git a/infra/envs/staging/bq_transfer_schedule.yaml b/infra/envs/staging/bq_transfer_schedule.yaml index ea768bde..ece4d852 100644 --- a/infra/envs/staging/bq_transfer_schedule.yaml +++ b/infra/envs/staging/bq_transfer_schedule.yaml @@ -17,5 +17,5 @@ kind: CronJob metadata: name: criticality-score-bq-transfer spec: - # At 12:00UTC each weekday. - schedule: "0 12 * * 1-5" + # At 4:00UTC, 14:00AEST each weekday. + schedule: "0 4 * * 1-5" diff --git a/infra/envs/staging/controller_schedule.yaml b/infra/envs/staging/controller_schedule.yaml index b04fc768..de29caa8 100644 --- a/infra/envs/staging/controller_schedule.yaml +++ b/infra/envs/staging/controller_schedule.yaml @@ -17,5 +17,5 @@ kind: CronJob metadata: name: criticality-score-batch-controller spec: - # At 02:00UTC each weekday. - schedule: "0 2 * * 1-5" + # At 0:30UTC, or 10:30AEST each weekday. + schedule: "30 0 * * 1-5" diff --git a/infra/envs/staging/csv_transfer_schedule.yaml b/infra/envs/staging/csv_transfer_schedule.yaml index e36c215c..74732ef7 100644 --- a/infra/envs/staging/csv_transfer_schedule.yaml +++ b/infra/envs/staging/csv_transfer_schedule.yaml @@ -17,5 +17,5 @@ kind: CronJob metadata: name: criticality-score-csv-transfer spec: - # At 12:00UTC each weekday. - schedule: "0 12 * * 1-5" + # At 4:00UTC, 14:00AEST each weekday. + schedule: "0 4 * * 1-5" From 14585f320df630a1ef4faa91746844849973acde Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 28 Nov 2022 17:02:09 +1100 Subject: [PATCH 141/172] Add the Git commit ID to the data produced by the worker. (#261) * Add the Git commit ID to the data produced by the worker. Signed-off-by: Caleb Brown * Small refactor to cache the commitID once per execution. Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- cmd/collect_signals/Dockerfile | 2 +- cmd/collect_signals/main.go | 5 +++++ cmd/collect_signals/vcs.go | 40 +++++++++++++++++++++++++++++++++ cmd/collect_signals/worker.go | 17 +++++++++++++- cmd/criticality_score/README.md | 6 ++--- 5 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 cmd/collect_signals/vcs.go diff --git a/cmd/collect_signals/Dockerfile b/cmd/collect_signals/Dockerfile index 16beec71..4d82b942 100644 --- a/cmd/collect_signals/Dockerfile +++ b/cmd/collect_signals/Dockerfile @@ -22,7 +22,7 @@ COPY . ./ FROM base AS collect_signals ARG TARGETOS ARG TARGETARCH -RUN CGO_ENABLED=0 go build ./cmd/collect_signals +RUN CGO_ENABLED=0 go build -buildvcs ./cmd/collect_signals RUN chmod -R 0775 /src/config/scorer/* FROM gcr.io/distroless/base:nonroot@sha256:533c15ef2acb1d3b1cd4e58d8aa2740900cae8f579243a53c53a6e28bcac0684 diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index db8d3d48..c616c6da 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -91,6 +91,11 @@ func main() { } defer logger.Sync() + // Embed the commitID with all log messages. + if commitID != "" { + logger = logger.With(zap.String("commit_id", commitID)) + } + // Extract the GCP project ID. gcpProjectID, err := config.GetProjectID() if err != nil { diff --git a/cmd/collect_signals/vcs.go b/cmd/collect_signals/vcs.go new file mode 100644 index 00000000..800b607c --- /dev/null +++ b/cmd/collect_signals/vcs.go @@ -0,0 +1,40 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package main + +import ( + "runtime/debug" +) + +const commitIDKey = "vcs.revision" + +var commitID = getCommitID() + +// getCommitID returns the vcs commit ID embedded in the binary when the +// -buildvcs flag is set while building. +func getCommitID() string { + info, ok := debug.ReadBuildInfo() + if !ok { + return "" + } + + for _, setting := range info.Settings { + if setting.Key == commitIDKey { + return setting.Value + } + } + + return "" +} diff --git a/cmd/collect_signals/worker.go b/cmd/collect_signals/worker.go index 1f938eeb..590af168 100644 --- a/cmd/collect_signals/worker.go +++ b/cmd/collect_signals/worker.go @@ -21,7 +21,10 @@ import ( "github.com/ossf/criticality_score/internal/signalio" ) -const collectionDateColumnName = "collection_date" +const ( + collectionDateColumnName = "collection_date" + commitIDColumnName = "worker_commit_id" +) type collectWorker struct { logger *zap.Logger @@ -51,6 +54,9 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq extras = append(extras, w.scoreColumnName) } extras = append(extras, collectionDateColumnName) + if commitID != "" { + extras = append(extras, commitIDColumnName) + } var jsonOutput bytes.Buffer jsonOut := signalio.JSONWriter(&jsonOutput) @@ -102,6 +108,15 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq Value: jobTime, }) + // Ensure the commit ID is included with each record for helping + // identify which Git commit is associated with this record. + if commitID != "" { + extras = append(extras, signalio.Field{ + Key: commitIDColumnName, + Value: commitID, + }) + } + // Write the signals to storage. if err := jsonOut.WriteSignals(ss, extras...); err != nil { return fmt.Errorf("failed writing signals: %w", err) diff --git a/cmd/criticality_score/README.md b/cmd/criticality_score/README.md index bc42405c..ffe8cdca 100644 --- a/cmd/criticality_score/README.md +++ b/cmd/criticality_score/README.md @@ -64,10 +64,10 @@ $ export GITHUB_TOKEN=ghp_abc,ghp_123 BigQuery access requires the "BigQuery User" (`roles/bigquery.user`) role added to the account used, or be an "Owner". -##### Option 1: `gcloud login` +##### Option 1: `gcloud auth login` -This option is useful during development. Run `gcloud login --update-adc` to -login to GCP and prepare application default credentials. +This option is useful during development. Run `gcloud auth login --update-adc` +to login to GCP and prepare application default credentials. ##### Option 2: GCE Service Worker From a568cc7fddb6583ea37454cce7092b2be5be9a3c Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Mon, 28 Nov 2022 23:53:33 -0600 Subject: [PATCH 142/172] Fixed lint warning (#259) - fixed ``` WARN [runner] The linter 'varcheck' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter. Replaced by unused. WARN [runner] The linter 'deadcode' is deprecated (since v1.49.0) due to: The owner seems to have abandoned the linter. Replaced by unused. ``` Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- .golangci.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 8761fd30..1f3aa1f7 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -17,7 +17,6 @@ linters: enable: - asciicheck #- bodyclose # Temporarily disabled. - - deadcode - depguard - dogsled #- errcheck # Temporarily disabled. @@ -59,7 +58,6 @@ linters: - unconvert - unparam - unused - - varcheck - whitespace #- wrapcheck linters-settings: From cb655412ce58bdad0c287b19adf37173d208b622 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Wed, 30 Nov 2022 19:58:04 -0600 Subject: [PATCH 143/172] Unit tests for Weighted Arithmetic Mean and Distribution (#248) * Unit tests for Weighted Arthmetic Mean - Added unit tests for WAM. Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Unit tests for distribution - Added unit tests for distribution Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed WAM issues - formatted WAM - formatted wam_test - Edited test for wam_test Addressed Code Review Comments - Included additional tests - Refactored structs within tests - Re-formatted code Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Refactored Code Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated based on code review comments Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Removed the ignored files Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed the validation after unmarshalling Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed code review comment Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed based on comment Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- .../scorer/algorithm/distribution_test.go | 155 ++++++++++++++++++ internal/scorer/algorithm/wam/wam_test.go | 105 ++++++++++++ internal/scorer/config.go | 9 +- 3 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 internal/scorer/algorithm/distribution_test.go create mode 100644 internal/scorer/algorithm/wam/wam_test.go diff --git a/internal/scorer/algorithm/distribution_test.go b/internal/scorer/algorithm/distribution_test.go new file mode 100644 index 00000000..517ce874 --- /dev/null +++ b/internal/scorer/algorithm/distribution_test.go @@ -0,0 +1,155 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package algorithm + +import ( + "math" + "testing" +) + +func TestLookupDistribution(t *testing.T) { + type result struct { + name string + value float64 + } + + //nolint:govet + tests := []struct { + name string + distributionName string + distributionValue float64 + want result + wantNil bool + }{ + { + name: "invalid name", + distributionName: "invalid", + + wantNil: true, + }, + { + name: "linear test", + + distributionName: "linear", + distributionValue: 300, + want: result{ + name: "linear", + value: 300, + }, + }, + { + name: "linear test with zero", + + distributionName: "linear", + distributionValue: 0, + want: result{ + name: "linear", + value: 0, + }, + }, + { + name: "negative linear test", + + distributionName: "linear", + distributionValue: -10, + + want: result{ + name: "linear", + value: -10, + }, + }, + { + name: "linear test with max int", + + distributionName: "linear", + distributionValue: math.MaxInt64, + + want: result{ + name: "linear", + value: math.MaxInt64, + }, + }, + { + name: "zipfian test", + + distributionName: "zipfian", + distributionValue: 300, + + want: result{ + name: "zipfian", + value: 5.707110264748875, + }, + }, + { + name: "zipfian test with zero", + + distributionName: "zipfian", + distributionValue: 0, + + want: result{ + name: "zipfian", + value: 0, + }, + }, + { + name: "negative zipfian test", + + distributionName: "zipfian", + distributionValue: -10, + + want: result{ + name: "zipfian", + value: math.NaN(), + }, + }, + { + name: "zipfian test with max int", + + distributionName: "zipfian", + distributionValue: math.MaxInt64, + + want: result{ + name: "zipfian", + value: 43.668272, + }, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := LookupDistribution(test.distributionName) + + if got == nil && test.wantNil { + return + } + + normalizedValue := got.Normalize(test.distributionValue) + + if got.String() != test.want.name { + t.Errorf("LookupDistribution name = %s, want name %s", got.String(), test.want.name) + } + + if math.IsNaN(normalizedValue) && math.IsNaN(test.want.value) { + // both are NaN, and we can't compare two NaNs together + return + } + + if math.Abs(test.want.value-normalizedValue) > 0.000001 { + // Making a comparison up to 6 decimal places, but this might not work for some cases with + // test.want.value and normalizedValue have a very small absolute difference + t.Errorf("LookupDistribution value %f, want value %f", normalizedValue, test.want.value) + } + }) + } +} diff --git a/internal/scorer/algorithm/wam/wam_test.go b/internal/scorer/algorithm/wam/wam_test.go new file mode 100644 index 00000000..bd92f3ac --- /dev/null +++ b/internal/scorer/algorithm/wam/wam_test.go @@ -0,0 +1,105 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package wam + +import ( + "errors" + "math" + "testing" + + "github.com/ossf/criticality_score/internal/scorer/algorithm" +) + +func TestWeighetedArithmeticMean_Score(t *testing.T) { + //nolint:govet + tests := []struct { + name string + inputs []*algorithm.Input + record map[string]float64 + want float64 + err error + }{ + { + name: "regular test", + inputs: []*algorithm.Input{ + { + Weight: 1, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("1")), + }, + { + Weight: 2, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("2")), + }, + { + Weight: 3, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("3")), + }, + { + Weight: 4, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("4")), + }, + { + Weight: 5, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("5")), + }, + }, + want: 3.6666666666666665, + record: map[string]float64{"1": 1, "2": 2, "3": 3, "4": 4, "5": 5}, + }, + { + name: "fields not matching the record", + inputs: []*algorithm.Input{ + { + Weight: 1, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("1")), + }, + }, + want: math.NaN(), + record: map[string]float64{"2": 2}, + }, + { + name: "some fields matching the record", + inputs: []*algorithm.Input{ + { + Weight: 1, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("1")), + }, + { + Weight: 2, Distribution: algorithm.LookupDistribution("linear"), + Source: algorithm.Value(algorithm.Field("2")), + }, + }, + want: 1, + record: map[string]float64{"1": 1}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + p, err := New(test.inputs) + + if err != nil && !errors.Is(err, test.err) { + t.Errorf("New() error = %v, wantErr %v", err, test.err) + } + if err != nil { + return + } + got := p.Score(test.record) + + if !(math.IsNaN(got) && math.IsNaN(test.want)) && got != test.want { + t.Errorf("Score() = %v, want %v", got, test.want) + } + }) + } +} diff --git a/internal/scorer/config.go b/internal/scorer/config.go index bfd7ddcb..33505e79 100644 --- a/internal/scorer/config.go +++ b/internal/scorer/config.go @@ -38,7 +38,7 @@ type Input struct { Weight float64 `yaml:"weight"` } -// Implements yaml.Unmarshaler interface. +// UnmarshalYAML Implements yaml.Unmarshaler interface. func (i *Input) UnmarshalYAML(value *yaml.Node) error { type RawInput Input raw := &RawInput{ @@ -51,7 +51,12 @@ func (i *Input) UnmarshalYAML(value *yaml.Node) error { if raw.Field == "" { return errors.New("field must be set") } + if raw.Weight <= 0 { + return errors.New("weight must be greater than 0") + } + *i = Input(*raw) + return nil } @@ -72,6 +77,7 @@ func buildCondition(c *Condition) (algorithm.Condition, error) { return nil, errors.New("one condition field must be set") } +// ToAlgorithmInput returns an instance of algorithm.Input that is constructed. func (i *Input) ToAlgorithmInput() (*algorithm.Input, error) { var v algorithm.Value v = algorithm.Field(i.Field) @@ -121,6 +127,7 @@ func LoadConfig(r io.Reader) (*Config, error) { if err := yaml.Unmarshal(data, c); err != nil { return nil, err } + return c, nil } From b1a355a59454a8b384c31aa2580e89a70bd113f0 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 1 Dec 2022 13:10:59 +1100 Subject: [PATCH 144/172] Ensure deps.dev data is fresh for each run of Criticality Score (#267) * Add "IF NOT EXISTS" to the caching query for deps.dev. This will *hopefully* avoid failures if multiple workers attempt to create the table at the same time. Signed-off-by: Caleb Brown * Set default TTL on dataset for deps.dev tables. This ensures tables only hang around for a short period of time. Signed-off-by: Caleb Brown * Add support for deps.dev expiration to the criticality_score tool. Signed-off-by: Caleb Brown * Add a jobID to collection to allow for per-job deps.dev tables. Signed-off-by: Caleb Brown * Fix lint warning Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- cmd/collect_signals/main.go | 13 ++ cmd/collect_signals/worker.go | 3 +- cmd/criticality_score/README.md | 7 +- cmd/criticality_score/main.go | 5 +- infra/envs/prod/config.yaml | 1 + infra/envs/staging/config.yaml | 1 + internal/collector/collector.go | 9 +- internal/collector/config.go | 11 ++ internal/collector/config_test.go | 9 ++ internal/collector/depsdev/bq.go | 30 ++++- internal/collector/depsdev/dependents.go | 124 +++++++++++++------- internal/collector/depsdev/source.go | 9 +- internal/collector/github/source.go | 4 +- internal/collector/githubmentions/source.go | 2 +- internal/collector/registry.go | 7 +- internal/collector/signal/source.go | 7 +- 16 files changed, 178 insertions(+), 64 deletions(-) diff --git a/cmd/collect_signals/main.go b/cmd/collect_signals/main.go index c616c6da..9dbc6eed 100644 --- a/cmd/collect_signals/main.go +++ b/cmd/collect_signals/main.go @@ -20,6 +20,7 @@ import ( "net/http" "net/rpc" "os" + "strconv" "strings" "time" @@ -108,6 +109,17 @@ func main() { gcpDatasetName = collector.DefaultGCPDatasetName } + // Extract the GCP dataset TTL. + gcpDatasetTTLHours := criticalityConfig["dataset-ttl-hours"] + gcpDatasetTTL := time.Duration(0) + if gcpDatasetTTLHours != "" { + i, err := strconv.Atoi(gcpDatasetTTLHours) + if err != nil { + logger.With(zap.Error(err)).Fatal("Failed to get GCP Dataset TTL") + } + gcpDatasetTTL = time.Hour * time.Duration(i) + } + // Determine whether scoring is enabled or disabled. // It supports various "truthy" and "fasley" values. It will default to // enabled. @@ -146,6 +158,7 @@ func main() { collector.EnableAllSources(), collector.GCPProject(gcpProjectID), collector.GCPDatasetName(gcpDatasetName), + collector.GCPDatasetTTL(gcpDatasetTTL), } w, err := NewWorker(context.Background(), logger, scoringEnabled, scoringConfigFile, scoringColumnName, csvBucketURL, opts) diff --git a/cmd/collect_signals/worker.go b/cmd/collect_signals/worker.go index 590af168..7949ac8b 100644 --- a/cmd/collect_signals/worker.go +++ b/cmd/collect_signals/worker.go @@ -39,6 +39,7 @@ type collectWorker struct { func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchRequest, bucketURL string) error { filename := worker.ResultFilename(req) jobTime := req.GetJobTime().AsTime() + jobID := jobTime.Format("20060102_150405") // Prepare the logger with identifiers for the shard and job. logger := w.logger.With( @@ -83,7 +84,7 @@ func (w *collectWorker) Process(ctx context.Context, req *data.ScorecardBatchReq repoLogger.With(zap.Error(err)).Warn("Failed to parse repo URL") continue } - ss, err := w.c.Collect(ctx, u) + ss, err := w.c.Collect(ctx, u, jobID) if err != nil { if errors.Is(err, collector.ErrUncollectableRepo) { repoLogger.With(zap.Error(err)).Warn("Repo is uncollectable") diff --git a/cmd/criticality_score/README.md b/cmd/criticality_score/README.md index ffe8cdca..1448d8da 100644 --- a/cmd/criticality_score/README.md +++ b/cmd/criticality_score/README.md @@ -126,7 +126,12 @@ fail. #### deps.dev Collection Flags - `-depsdev-disable` disables the collection of signals from deps.dev. -- `-depsdev-dataset string` the BigQuery dataset name to use. Default is `depsdev_analysis`. +- `-depsdev-dataset string` the BigQuery dataset name to use. Default is + `depsdev_analysis`. +- `-depsdev-expiration hours` the default time-to-live or expiration for tables + created in the BigQuery dataset. New tables will be deleted after this + period. Expiration times on existing tables in the dataset won't be changed. + Default is `0` (no expiration). #### Scoring flags diff --git a/cmd/criticality_score/main.go b/cmd/criticality_score/main.go index 832d720a..b6a98254 100644 --- a/cmd/criticality_score/main.go +++ b/cmd/criticality_score/main.go @@ -24,6 +24,7 @@ import ( "os" "path" "strings" + "time" "go.uber.org/zap" "go.uber.org/zap/zapcore" @@ -42,6 +43,7 @@ var ( gcpProjectFlag = flag.String("gcp-project-id", "", "the Google Cloud Project ID to use. Auto-detects by default.") depsdevDisableFlag = flag.Bool("depsdev-disable", false, "disables the collection of signals from deps.dev.") depsdevDatasetFlag = flag.String("depsdev-dataset", collector.DefaultGCPDatasetName, "the BigQuery dataset name to use.") + depsdevTTLFlag = flag.Int("depsdev-expiration", 0, "the default expiration (`hours`) to use for deps.dev tables. No expiration by default.") scoringDisableFlag = flag.Bool("scoring-disable", false, "disables the generation of scores.") scoringConfigFlag = flag.String("scoring-config", "", "path to a YAML file for configuring the scoring algorithm.") scoringColumnNameFlag = flag.String("scoring-column", "", "manually specify the name for the column used to hold the score.") @@ -145,6 +147,7 @@ func main() { collector.EnableAllSources(), collector.GCPProject(*gcpProjectFlag), collector.GCPDatasetName(*depsdevDatasetFlag), + collector.GCPDatasetTTL(time.Hour * time.Duration(*depsdevTTLFlag)), } if *depsdevDisableFlag { opts = append(opts, collector.DisableSource(collector.SourceTypeDepsDev)) @@ -191,7 +194,7 @@ func main() { innerLogger := logger.With(zap.Int("worker", worker)) for u := range repos { l := innerLogger.With(zap.String("url", u.String())) - ss, err := c.Collect(ctx, u) + ss, err := c.Collect(ctx, u, "") if err != nil { if errors.Is(err, collector.ErrUncollectableRepo) { l.With( diff --git a/infra/envs/prod/config.yaml b/infra/envs/prod/config.yaml index ef75b7f6..cc6ea687 100644 --- a/infra/envs/prod/config.yaml +++ b/infra/envs/prod/config.yaml @@ -33,6 +33,7 @@ additional-params: log-env: gcp log-level: info dataset: ossf_criticality_score_depsdev + dataset-ttl-hours: 672 # 4 weeks scoring: enabled scoring-config: config/scorer/pike_depsdev.yml scoring-column-name: default_score diff --git a/infra/envs/staging/config.yaml b/infra/envs/staging/config.yaml index 04ba1a66..c93b4136 100644 --- a/infra/envs/staging/config.yaml +++ b/infra/envs/staging/config.yaml @@ -33,6 +33,7 @@ additional-params: log-env: gcp log-level: info dataset: ossf_criticality_score_depsdev_staging + dataset-ttl-hours: 168 # 1 week scoring: enabled scoring-config: config/scorer/pike_depsdev.yml scoring-column-name: default_score diff --git a/internal/collector/collector.go b/internal/collector/collector.go index b636c799..7bb9c97b 100644 --- a/internal/collector/collector.go +++ b/internal/collector/collector.go @@ -81,7 +81,7 @@ func New(ctx context.Context, logger *zap.Logger, opts ...Option) (*Collector, e // deps.dev collection source has been disabled, so skip it. logger.Warn("deps.dev signal source is disabled.") } else { - ddsource, err := depsdev.NewSource(ctx, logger, c.config.gcpProject, c.config.gcpDatasetName) + ddsource, err := depsdev.NewSource(ctx, logger, c.config.gcpProject, c.config.gcpDatasetName, c.config.gcpDatasetTTL) if err != nil { return nil, fmt.Errorf("init deps.dev source: %w", err) } @@ -99,7 +99,10 @@ func (c *Collector) EmptySets() []signal.Set { } // Collect gathers and returns all the signals for the given project repo url. -func (c *Collector) Collect(ctx context.Context, u *url.URL) ([]signal.Set, error) { +// +// An optional jobID can be specified which can be used by underlying sources to +// manage caching. For simple usage this can be the empty string. +func (c *Collector) Collect(ctx context.Context, u *url.URL, jobID string) ([]signal.Set, error) { l := c.config.logger.With(zap.String("url", u.String())) repo, err := c.resolver.Resolve(ctx, u) @@ -116,7 +119,7 @@ func (c *Collector) Collect(ctx context.Context, u *url.URL) ([]signal.Set, erro l = l.With(zap.String("canonical_url", repo.URL().String())) l.Info("Collecting") - ss, err := c.registry.Collect(ctx, repo) + ss, err := c.registry.Collect(ctx, repo, jobID) if err != nil { return nil, fmt.Errorf("collecting project: %w", err) } diff --git a/internal/collector/config.go b/internal/collector/config.go index aa9dc1f6..26088317 100644 --- a/internal/collector/config.go +++ b/internal/collector/config.go @@ -18,6 +18,7 @@ import ( "context" "fmt" "net/http" + "time" "github.com/go-logr/zapr" "github.com/ossf/scorecard/v4/clients/githubrepo/roundtripper" @@ -72,6 +73,7 @@ type config struct { gcpProject string gcpDatasetName string + gcpDatasetTTL time.Duration sourceStatuses map[SourceType]sourceStatus defaultSourceStatus sourceStatus @@ -94,6 +96,7 @@ func makeConfig(ctx context.Context, logger *zap.Logger, opts ...Option) *config gitHubHTTPClient: defaultGitHubHTTPClient(ctx, logger), gcpProject: "", gcpDatasetName: DefaultGCPDatasetName, + gcpDatasetTTL: time.Duration(0), } for _, opt := range opts { @@ -175,3 +178,11 @@ func GCPDatasetName(n string) Option { c.gcpDatasetName = n }) } + +// GCPDatasetTTL sets the time-to-live for tables created with GCP BigQuery +// datasets. +func GCPDatasetTTL(ttl time.Duration) Option { + return option(func(c *config) { + c.gcpDatasetTTL = ttl + }) +} diff --git a/internal/collector/config_test.go b/internal/collector/config_test.go index f9e74631..1d12c891 100644 --- a/internal/collector/config_test.go +++ b/internal/collector/config_test.go @@ -17,6 +17,7 @@ package collector import ( "context" "testing" + "time" "go.uber.org/zap/zaptest" ) @@ -80,6 +81,14 @@ func TestGCPDatasetName(t *testing.T) { } } +func TestGCPDatasetTTL(t *testing.T) { + want := time.Duration(24) * time.Hour + c := makeTestConfig(t, GCPDatasetTTL(want)) + if c.gcpDatasetTTL != want { + t.Fatalf("config.gcpDatasetTTL = %q, want %q", c.gcpDatasetTTL, want) + } +} + func makeTestConfig(t *testing.T, opts ...Option) *config { t.Helper() return makeConfig(context.Background(), zaptest.NewLogger(t), opts...) diff --git a/internal/collector/depsdev/bq.go b/internal/collector/depsdev/bq.go index ca8c2ac0..9da3e226 100644 --- a/internal/collector/depsdev/bq.go +++ b/internal/collector/depsdev/bq.go @@ -17,6 +17,8 @@ package depsdev import ( "context" "errors" + "fmt" + "time" "cloud.google.com/go/bigquery" "google.golang.org/api/googleapi" @@ -39,7 +41,8 @@ type bqAPI interface { OneResultQuery(ctx context.Context, query string, params map[string]any, result any) error NoResultQuery(ctx context.Context, query string, params map[string]any) error GetDataset(ctx context.Context, id string) (*Dataset, error) - CreateDataset(ctx context.Context, id string) (*Dataset, error) + CreateDataset(ctx context.Context, id string, ttl time.Duration) (*Dataset, error) + UpdateDataset(ctx context.Context, d *Dataset, ttl time.Duration) error GetTable(ctx context.Context, d *Dataset, id string) (*Table, error) } @@ -96,16 +99,16 @@ func (b *bq) GetDataset(ctx context.Context, id string) (*Dataset, error) { return nil, nil } if err != nil { - return nil, err + return nil, fmt.Errorf("dataset metadata: %w", err) } return &Dataset{ ds: ds, }, nil } -func (b *bq) CreateDataset(ctx context.Context, id string) (*Dataset, error) { +func (b *bq) CreateDataset(ctx context.Context, id string, ttl time.Duration) (*Dataset, error) { ds := b.client.Dataset(id) - if err := ds.Create(ctx, &bigquery.DatasetMetadata{}); err != nil { + if err := ds.Create(ctx, &bigquery.DatasetMetadata{DefaultTableExpiration: ttl}); err != nil { return nil, err } return &Dataset{ @@ -113,6 +116,25 @@ func (b *bq) CreateDataset(ctx context.Context, id string) (*Dataset, error) { }, nil } +func (b *bq) UpdateDataset(ctx context.Context, d *Dataset, ttl time.Duration) error { + md, err := d.ds.Metadata(ctx) + if err != nil { + return fmt.Errorf("dataset metadata: %w", err) + } + var update bigquery.DatasetMetadataToUpdate + needsWrite := false + if md.DefaultTableExpiration != ttl { + update.DefaultTableExpiration = ttl + needsWrite = true + } + if needsWrite { + if _, err := d.ds.Update(ctx, update, ""); err != nil { + return fmt.Errorf("dataset update metadata: %w", err) + } + } + return nil +} + func (b *bq) GetTable(ctx context.Context, d *Dataset, id string) (*Table, error) { t := d.ds.Table(id) md, err := t.Metadata(ctx) diff --git a/internal/collector/depsdev/dependents.go b/internal/collector/depsdev/dependents.go index c6bc1901..de994a75 100644 --- a/internal/collector/depsdev/dependents.go +++ b/internal/collector/depsdev/dependents.go @@ -18,6 +18,7 @@ import ( "bytes" "context" "errors" + "fmt" "text/template" "time" @@ -46,7 +47,7 @@ AS WHERE d.SnapshotAt = @part GROUP BY Name, Version, System; -CREATE TABLE ` + "`{{.ProjectID}}.{{.DatasetName}}.{{.TableName}}`" + ` +CREATE TABLE IF NOT EXISTS ` + "`{{.ProjectID}}.{{.DatasetName}}.{{.TableName}}`" + ` AS WITH pvp AS ( SELECT System, Name, Version, ProjectName, ProjectType @@ -66,7 +67,7 @@ FROM ` + "`{{.ProjectID}}.{{.DatasetName}}.{{.TableName}}`" + ` WHERE ProjectName = @projectname AND ProjectType = @projecttype; ` -func NewDependents(ctx context.Context, client *bigquery.Client, logger *zap.Logger, datasetName string) (*dependents, error) { +func NewDependents(ctx context.Context, client *bigquery.Client, logger *zap.Logger, datasetName string, datasetTTL time.Duration) (*dependents, error) { b := &bq{client: client} c := &dependents{ b: b, @@ -75,62 +76,50 @@ func NewDependents(ctx context.Context, client *bigquery.Client, logger *zap.Log zap.String("dataset", datasetName), ), datasetName: datasetName, + datasetTTL: datasetTTL, } var err error - // Populate the snapshot time - c.snapshotTime, err = c.getLatestSnapshotTime(ctx) - if err != nil { - return nil, err - } - // Ensure the dataset exists - ds, err := c.getOrCreateDataset(ctx) + c.ds, err = c.getOrCreateDataset(ctx) if err != nil { return nil, err } - // Ensure the dependent count table exists and is populated - t, err := c.b.GetTable(ctx, ds, dependentCountsTableName) - if err != nil { - return nil, err - } - if t != nil { - c.logger.Warn("dependent count table exists") - } else { - c.logger.Warn("creating dependent count table") - err := c.b.NoResultQuery(ctx, c.generateQuery(dataQuery), map[string]any{"part": c.snapshotTime}) - if err != nil { - return nil, err - } - } - - // Cache the data query to avoid re-generating it repeatedly. - c.countQuery = c.generateQuery(countQuery) - return c, nil } +type cache struct { + countQuery string + tableKey string +} + type dependents struct { b bqAPI logger *zap.Logger - snapshotTime time.Time - countQuery string + ds *Dataset + lastUseCache *cache datasetName string + datasetTTL time.Duration } -func (c *dependents) generateQuery(temp string) string { - t := template.Must(template.New("query").Parse(temp)) +func (c *dependents) generateQuery(queryTemplate, tableName string) string { + t := template.Must(template.New("query").Parse(queryTemplate)) var b bytes.Buffer t.Execute(&b, struct { ProjectID string DatasetName string TableName string - }{c.b.Project(), c.datasetName, dependentCountsTableName}) + }{c.b.Project(), c.datasetName, tableName}) return b.String() } -func (c *dependents) Count(ctx context.Context, projectName, projectType string) (int, bool, error) { +func (c *dependents) Count(ctx context.Context, projectName, projectType, tableKey string) (int, bool, error) { + query, err := c.prepareCountQuery(ctx, tableKey) + if err != nil { + return 0, false, fmt.Errorf("prepare count query: %w", err) + } + var rec struct { DependentCount int } @@ -138,18 +127,14 @@ func (c *dependents) Count(ctx context.Context, projectName, projectType string) "projectname": projectName, "projecttype": projectType, } - err := c.b.OneResultQuery(ctx, c.countQuery, params, &rec) + err = c.b.OneResultQuery(ctx, query, params, &rec) if err == nil { return rec.DependentCount, true, nil } if errors.Is(err, ErrorNoResults) { return 0, false, nil } - return 0, false, err -} - -func (c *dependents) LatestSnapshotTime() time.Time { - return c.snapshotTime + return 0, false, fmt.Errorf("count query: %w", err) } func (c *dependents) getLatestSnapshotTime(ctx context.Context) (time.Time, error) { @@ -157,7 +142,7 @@ func (c *dependents) getLatestSnapshotTime(ctx context.Context) (time.Time, erro SnapshotTime time.Time } if err := c.b.OneResultQuery(ctx, snapshotQuery, nil, &rec); err != nil { - return time.Time{}, err + return time.Time{}, fmt.Errorf("snapshot query: %w", err) } return rec.SnapshotTime, nil } @@ -166,17 +151,70 @@ func (c *dependents) getOrCreateDataset(ctx context.Context) (*Dataset, error) { // Attempt to get the current dataset ds, err := c.b.GetDataset(ctx, c.datasetName) if err != nil { - return nil, err + return nil, fmt.Errorf("get dataset: %w", err) } if ds == nil { // Dataset doesn't exist so create it c.logger.Debug("creating dependent count dataset") - ds, err = c.b.CreateDataset(ctx, c.datasetName) + ds, err = c.b.CreateDataset(ctx, c.datasetName, c.datasetTTL) if err != nil { - return nil, err + return nil, fmt.Errorf("create dataset: %w", err) } } else { c.logger.Debug("dependent count dataset exists") } + // Ensure the dataset is consistent with the settings. + err = c.b.UpdateDataset(ctx, ds, c.datasetTTL) + if err != nil { + return nil, fmt.Errorf("update dataset: %w", err) + } return ds, nil } + +func (c *dependents) prepareCountQuery(ctx context.Context, tableKey string) (string, error) { + // If the last use is the same as this usage, avoid needlessly checking if + // the table exists. + if c.lastUseCache != nil && c.lastUseCache.tableKey == tableKey { + c.logger.Debug("Using cached dependent count query") + return c.lastUseCache.countQuery, nil + } + + // Generate the table name + tableName := getTableName(tableKey) + + // Ensure the dependent count table exists and is populated + t, err := c.b.GetTable(ctx, c.ds, tableName) + if err != nil { + return "", fmt.Errorf("get table: %w", err) + } + if t != nil { + c.logger.Info("Dependent count table exists") + } else { + c.logger.Info("Creating dependent count table") + // Always get the latest snapshot time to ensure the partition used is + // the latest possible partition. + snapshotTime, err := c.getLatestSnapshotTime(ctx) + if err != nil { + return "", fmt.Errorf("get latest snapshot time: %w", err) + } + // This query use "IF NOT EXISTS" to avoid failing if two or more + // workers execute this code at the same time. + err = c.b.NoResultQuery(ctx, c.generateQuery(dataQuery, tableName), map[string]any{"part": snapshotTime}) + if err != nil { + return "", fmt.Errorf("create table: %w", err) + } + } + + c.lastUseCache = &cache{ + tableKey: tableKey, + countQuery: c.generateQuery(countQuery, tableName), + } + return c.lastUseCache.countQuery, nil +} + +func getTableName(tableKey string) string { + if tableKey == "" { + return dependentCountsTableName + } + return dependentCountsTableName + "_" + tableKey +} diff --git a/internal/collector/depsdev/source.go b/internal/collector/depsdev/source.go index 71779076..4b33d7e2 100644 --- a/internal/collector/depsdev/source.go +++ b/internal/collector/depsdev/source.go @@ -18,6 +18,7 @@ import ( "context" "net/url" "strings" + "time" "cloud.google.com/go/bigquery" "go.uber.org/zap" @@ -53,14 +54,14 @@ func (c *depsDevSource) IsSupported(r projectrepo.Repo) bool { return t != "" } -func (c *depsDevSource) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (c *depsDevSource) Get(ctx context.Context, r projectrepo.Repo, jobID string) (signal.Set, error) { var s depsDevSet n, t := parseRepoURL(r.URL()) if t == "" { return &s, nil } c.logger.With(zap.String("url", r.URL().String())).Debug("Fetching deps.dev dependent count") - deps, found, err := c.dependents.Count(ctx, n, t) + deps, found, err := c.dependents.Count(ctx, n, t, jobID) if err != nil { return nil, err } @@ -75,7 +76,7 @@ func (c *depsDevSource) Get(ctx context.Context, r projectrepo.Repo) (signal.Set // TODO add options to configure the dataset: // - force dataset re-creation (-update-strategy = always,stale,weekly,monthly,never) // - force dataset destruction (-depsdev-destroy-data) -func NewSource(ctx context.Context, logger *zap.Logger, projectID, datasetName string) (signal.Source, error) { +func NewSource(ctx context.Context, logger *zap.Logger, projectID, datasetName string, datasetTTL time.Duration) (signal.Source, error) { if projectID == "" { projectID = bigquery.DetectProjectID } @@ -86,7 +87,7 @@ func NewSource(ctx context.Context, logger *zap.Logger, projectID, datasetName s // Set the location gcpClient.Location = defaultLocation - dependents, err := NewDependents(ctx, gcpClient, logger, datasetName) + dependents, err := NewDependents(ctx, gcpClient, logger, datasetName, datasetTTL) if err != nil { return nil, err } diff --git a/internal/collector/github/source.go b/internal/collector/github/source.go index acd8e7d3..80ce50ba 100644 --- a/internal/collector/github/source.go +++ b/internal/collector/github/source.go @@ -30,7 +30,7 @@ func (rc *RepoSource) EmptySet() signal.Set { return &signal.RepoSet{} } -func (rc *RepoSource) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (rc *RepoSource) Get(ctx context.Context, r projectrepo.Repo, _ string) (signal.Set, error) { ghr, ok := r.(*repo) if !ok { return nil, errors.New("project is not a github project") @@ -91,7 +91,7 @@ func (ic *IssuesSource) EmptySet() signal.Set { return &signal.IssuesSet{} } -func (ic *IssuesSource) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (ic *IssuesSource) Get(ctx context.Context, r projectrepo.Repo, _ string) (signal.Set, error) { ghr, ok := r.(*repo) if !ok { return nil, errors.New("project is not a github project") diff --git a/internal/collector/githubmentions/source.go b/internal/collector/githubmentions/source.go index 46e456ab..4ef8208a 100644 --- a/internal/collector/githubmentions/source.go +++ b/internal/collector/githubmentions/source.go @@ -59,7 +59,7 @@ func (c *Source) IsSupported(r projectrepo.Repo) bool { return true } -func (c *Source) Get(ctx context.Context, r projectrepo.Repo) (signal.Set, error) { +func (c *Source) Get(ctx context.Context, r projectrepo.Repo, _ string) (signal.Set, error) { s := &mentionSet{} if c, err := c.githubSearchTotalCommitMentions(ctx, r.URL()); err != nil { return nil, err diff --git a/internal/collector/registry.go b/internal/collector/registry.go index a807d899..b71e6322 100644 --- a/internal/collector/registry.go +++ b/internal/collector/registry.go @@ -103,11 +103,14 @@ func (r *registry) EmptySets() []signal.Set { } // Collect will collect all the signals for the given repo. -func (r *registry) Collect(ctx context.Context, repo projectrepo.Repo) ([]signal.Set, error) { +// +// An optinal jobID can be specified which is used by some sources for managing +// caches. +func (r *registry) Collect(ctx context.Context, repo projectrepo.Repo, jobID string) ([]signal.Set, error) { cs := r.sourcesForRepository(repo) var ss []signal.Set for _, c := range cs { - s, err := c.Get(ctx, repo) + s, err := c.Get(ctx, repo, jobID) if err != nil { return nil, err } diff --git a/internal/collector/signal/source.go b/internal/collector/signal/source.go index 5a508764..e508667d 100644 --- a/internal/collector/signal/source.go +++ b/internal/collector/signal/source.go @@ -29,9 +29,12 @@ type Source interface { // IsSupported returns true if the Source supports the supplied Repo. IsSupported(projectrepo.Repo) bool - // Get gathers and returns a Set of signals for the given project repo. + // Get gathers and returns a Set of signals for the given project repo r. + // + // An optional string jobID can be specified and may be used by the Source + // to manage caches related to a collection run. // // An error is returned if it is unable to successfully gather the signals, // or if the context is cancelled. - Get(context.Context, projectrepo.Repo) (Set, error) + Get(ctx context.Context, r projectrepo.Repo, jobID string) (Set, error) } From 62816c19011ecb9db46ff24f28baac62392f584e Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 1 Dec 2022 14:37:37 +1100 Subject: [PATCH 145/172] Add /tools to dependabot config (#270) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- .github/dependabot.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 28f34c2d..4e348979 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,6 +10,11 @@ updates: schedule: interval: daily open-pull-requests-limit: 10 +- package-ecosystem: gomod + directory: "/tools" + schedule: + interval: daily + open-pull-requests-limit: 5 - package-ecosystem: "github-actions" directory: "/" schedule: From 07f810f0ee170e47a421191e7054366d8d31b6e0 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Sun, 4 Dec 2022 18:49:37 -0600 Subject: [PATCH 146/172] Makefile: Included gofumpt target (#266) * Makefile: Included gofumpt target - Included gofumpt target to format the code. - Will make it easier for new contributors. Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Changed based on code review comments Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Changed gofumpt to format Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- Makefile | 9 +- go.work.sum | 251 +++++++++++++++++++++++++++++++++++++++++++++++++ tools/tools.go | 1 + 3 files changed, 260 insertions(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 98d670da..3adbe32c 100644 --- a/Makefile +++ b/Makefile @@ -13,6 +13,7 @@ # limitations under the License. IMAGE_NAME = criticality-score GOLANGCI_LINT := golangci-lint +GOFUMPT := gofumpt default: help @@ -37,6 +38,12 @@ lint: ## Run linter lint: $(GOLANGCI_LINT) $(GOLANGCI_LINT) run -c .golangci.yml +.PHONY: format +$(GOFUMPT): install/deps +format: ## Run formatter +format: $(GOFUMPT) + $(GOFUMPT) -w -l . + docker-targets = build/docker/enumerate-github build/docker/criticality-score build/docker/collect-signals build/docker/csv-transfer .PHONY: build/docker $(docker-targets) build/docker: $(docker-targets) ## Build all docker targets @@ -52,4 +59,4 @@ build/docker/csv-transfer: .PHONY: install/deps install/deps: ## Installs all dependencies during development and building @echo Installing tools from tools/tools.go - @cd tools; cat tools.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go install % + @cd tools; cat tools.go | grep _ | awk -F'"' '{print $$2}' | xargs -tI % go install % \ No newline at end of file diff --git a/go.work.sum b/go.work.sum index 64afe24c..4434a7f6 100644 --- a/go.work.sum +++ b/go.work.sum @@ -1,116 +1,356 @@ +cloud.google.com/go/aiplatform v1.24.0 h1:QqHZT1IMldf/daXoSnkJWBIqGBsw50X+xP6HSVzLRPo= cloud.google.com/go/aiplatform v1.24.0/go.mod h1:67UUvRBKG6GTayHKV8DBv2RtR1t93YRu5B1P3x99mYY= +cloud.google.com/go/analytics v0.12.0 h1:NKw6PpQi6V1O+KsjuTd+bhip9d0REYu4NevC45vtGp8= cloud.google.com/go/analytics v0.12.0/go.mod h1:gkfj9h6XRf9+TS4bmuhPEShsh3hH8PAZzm/41OOhQd4= +cloud.google.com/go/area120 v0.6.0 h1:TCMhwWEWhCn8d44/Zs7UCICTWje9j3HuV6nVGMjdpYw= cloud.google.com/go/area120 v0.6.0/go.mod h1:39yFJqWVgm0UZqWTOdqkLhjoC7uFfgXRC8g/ZegeAh0= +cloud.google.com/go/artifactregistry v1.7.0 h1:9yKYCozdh29v7QMx3QBuksZGtPNICFb5SVnyNvkKRGg= cloud.google.com/go/artifactregistry v1.7.0/go.mod h1:mqTOFOnGZx8EtSqK/ZWcsm/4U8B77rbcLP6ruDU2Ixk= +cloud.google.com/go/asset v1.8.0 h1:qzYOcI6u4CD+0R1E8rWbrqs04fISCcg2YYxW8yBAqFM= cloud.google.com/go/asset v1.8.0/go.mod h1:mUNGKhiqIdbr8X7KNayoYvyc4HbbFO9URsjbytpUaW0= +cloud.google.com/go/assuredworkloads v1.7.0 h1:IYhjgcgwb5TIAhC0aWQGGOqBnP0c2xijgMGf1iJRs50= cloud.google.com/go/assuredworkloads v1.7.0/go.mod h1:z/736/oNmtGAyU47reJgGN+KVoYoxeLBoj4XkKYscNI= +cloud.google.com/go/automl v1.6.0 h1:U+kHmeKGXgBvTlrecPJhwkItWaIpIscG5DUpQxBQZZg= cloud.google.com/go/automl v1.6.0/go.mod h1:ugf8a6Fx+zP0D59WLhqgTDsQI9w07o64uf/Is3Nh5p8= cloud.google.com/go/bigquery v1.42.0/go.mod h1:8dRTJxhtG+vwBKzE5OseQn/hiydoQN3EedCaOdYmxRA= +cloud.google.com/go/billing v1.5.0 h1:4RESn+mA7eGPBr5eQ4B/hbkHNivzYHbgRWpdlNeNjiE= cloud.google.com/go/billing v1.5.0/go.mod h1:mztb1tBc3QekhjSgmpf/CV4LzWXLzCArwpLmP2Gm88s= +cloud.google.com/go/binaryauthorization v1.2.0 h1:5F7dowxGuYQlX3LjfjH/sKf+IvI1TsItTw0sDZmoec4= cloud.google.com/go/binaryauthorization v1.2.0/go.mod h1:86WKkJHtRcv5ViNABtYMhhNWRrD1Vpi//uKEy7aYEfI= +cloud.google.com/go/cloudtasks v1.6.0 h1:IL5W4fh6dAq9x1mO+4evrWCISOmPJegdaO0hZRZmWNE= cloud.google.com/go/cloudtasks v1.6.0/go.mod h1:C6Io+sxuke9/KNRkbQpihnW93SWDU3uXt92nu85HkYI= cloud.google.com/go/compute v1.10.0/go.mod h1:ER5CLbMxl90o2jtNbGSbtfOpQKR0t15FOtRsugnLrlU= cloud.google.com/go/compute/metadata v0.1.0/go.mod h1:Z1VN+bulIf6bt4P/C37K4DyZYZEXYonfTBHHFPO/4UU= +cloud.google.com/go/containeranalysis v0.6.0 h1:2824iym832ljKdVpCBnpqm5K94YT/uHTVhNF+dRTXPI= cloud.google.com/go/containeranalysis v0.6.0/go.mod h1:HEJoiEIu+lEXM+k7+qLCci0h33lX3ZqoYFdmPcoO7s4= cloud.google.com/go/datacatalog v1.6.0/go.mod h1:+aEyF8JKg+uXcIdAmmaMUmZ3q1b/lKLtXCmXdnc0lbc= +cloud.google.com/go/dataflow v0.7.0 h1:CW3541Fm7KPTyZjJdnX6NtaGXYFn5XbFC5UcjgALKvU= cloud.google.com/go/dataflow v0.7.0/go.mod h1:PX526vb4ijFMesO1o202EaUmouZKBpjHsTlCtB4parQ= +cloud.google.com/go/dataform v0.4.0 h1:fnwkyzCVcPI/TmBheGgpmK2h+hWUIDHcZBincHRhrQ0= cloud.google.com/go/dataform v0.4.0/go.mod h1:fwV6Y4Ty2yIFL89huYlEkwUPtS7YZinZbzzj5S9FzCE= +cloud.google.com/go/datalabeling v0.6.0 h1:dp8jOF21n/7jwgo/uuA0RN8hvLcKO4q6s/yvwevs2ZM= cloud.google.com/go/datalabeling v0.6.0/go.mod h1:WqdISuk/+WIGeMkpw/1q7bK/tFEZxsrFJOJdY2bXvTQ= +cloud.google.com/go/dataqna v0.6.0 h1:gx9jr41ytcA3dXkbbd409euEaWtofCVXYBvJz3iYm18= cloud.google.com/go/dataqna v0.6.0/go.mod h1:1lqNpM7rqNLVgWBJyk5NF6Uen2PHym0jtVJonplVsDA= +cloud.google.com/go/datastore v1.1.0 h1:/May9ojXjRkPBNVrq+oWLqmWCkr4OU5uRY29bu0mRyQ= +cloud.google.com/go/datastream v1.3.0 h1:ula4YR2K66o5wifLdPQMtR2I6KP+zvqdSEb6ncd1e0g= cloud.google.com/go/datastream v1.3.0/go.mod h1:cqlOX8xlyYF/uxhiKn6Hbv6WjwPPuI9W2M9SAXwaLLQ= +cloud.google.com/go/dialogflow v1.17.0 h1:NU0Pj57H++JQOW225/7o34sUZ4i9/TLfWFOSbI3N1cY= cloud.google.com/go/dialogflow v1.17.0/go.mod h1:YNP09C/kXA1aZdBgC/VtXX74G/TKn7XVCcVumTflA+8= +cloud.google.com/go/documentai v1.8.0 h1:CipwaecNhtsWUSneV2J5y8OqudHqvqPlcMHgSyh8vak= cloud.google.com/go/documentai v1.8.0/go.mod h1:xGHNEB7CtsnySCNrCFdCyyMz44RhFEEX2Q7UD0c5IhU= +cloud.google.com/go/domains v0.7.0 h1:pu3JIgC1rswIqi5romW0JgNO6CTUydLYX8zyjiAvO1c= cloud.google.com/go/domains v0.7.0/go.mod h1:PtZeqS1xjnXuRPKE/88Iru/LdfoRyEHYA9nFQf4UKpg= +cloud.google.com/go/edgecontainer v0.2.0 h1:hd6J2n5dBBRuAqnNUEsKWrp6XNPKsaxwwIyzOPZTokk= cloud.google.com/go/edgecontainer v0.2.0/go.mod h1:RTmLijy+lGpQ7BXuTDa4C4ssxyXT34NIuHIgKuP4s5w= +cloud.google.com/go/firestore v1.6.1 h1:8rBq3zRjnHx8UtBvaOWqBB1xq9jH6/wltfQLlTMh2Fw= +cloud.google.com/go/functions v1.7.0 h1:s3Snbr2O4j4p7CuwImBas8rNNmkHS1YJANcCpKGqQSE= cloud.google.com/go/functions v1.7.0/go.mod h1:+d+QBcWM+RsrgZfV9xo6KfA1GlzJfxcfZcRPEhDDfzg= +cloud.google.com/go/gaming v1.6.0 h1:PKggmegChZulPW8yvtziF8P9UOuVFwbvylbEucTNups= cloud.google.com/go/gaming v1.6.0/go.mod h1:YMU1GEvA39Qt3zWGyAVA9bpYz/yAhTvaQ1t2sK4KPUA= +cloud.google.com/go/gkeconnect v0.6.0 h1:zAcvDa04tTnGdu6TEZewaLN2tdMtUOJJ7fEceULjguA= cloud.google.com/go/gkeconnect v0.6.0/go.mod h1:Mln67KyU/sHJEBY8kFZ0xTeyPtzbq9StAVvEULYK16A= +cloud.google.com/go/gkehub v0.10.0 h1:JTcTaYQRGsVm+qkah7WzHb6e9sf1C0laYdRPn9aN+vg= cloud.google.com/go/gkehub v0.10.0/go.mod h1:UIPwxI0DsrpsVoWpLB0stwKCP+WFVG9+y977wO+hBH0= +cloud.google.com/go/kms v1.4.0 h1:iElbfoE61VeLhnZcGOltqL8HIly8Nhbe5t6JlH9GXjo= +cloud.google.com/go/language v1.6.0 h1:Fb2iua/5/UBvUuW9PgBinwsCRDi1qoQJEuekOinHFCs= cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI= +cloud.google.com/go/lifesciences v0.6.0 h1:tIqhivE2LMVYkX0BLgG7xL64oNpDaFFI7teunglt1tI= cloud.google.com/go/lifesciences v0.6.0/go.mod h1:ddj6tSX/7BOnhxCSd3ZcETvtNr8NZ6t/iPhY2Tyfu08= +cloud.google.com/go/mediatranslation v0.6.0 h1:qAJzpxmEX+SeND10Y/4868L5wfZpo4Y3BIEnIieP4dk= cloud.google.com/go/mediatranslation v0.6.0/go.mod h1:hHdBCTYNigsBxshbznuIMFNe5QXEowAuNmmC7h8pu5w= +cloud.google.com/go/memcache v1.5.0 h1:qTBOiSnVw7rnW6GVeH5Br8qs80ILoflNgFZySvaT4ek= cloud.google.com/go/memcache v1.5.0/go.mod h1:dk3fCK7dVo0cUU2c36jKb4VqKPS22BTkf81Xq617aWM= +cloud.google.com/go/metastore v1.6.0 h1:wzJ9HslsybiJ3HL2168dVonr9D/eBq0VqObiMSCrE6c= cloud.google.com/go/metastore v1.6.0/go.mod h1:6cyQTls8CWXzk45G55x57DVQ9gWg7RiH65+YgPsNh9s= cloud.google.com/go/monitoring v1.5.0 h1:ZltYv8e69fJVga7RTthUBGdx4+Pwz6GRF1V3zylERl4= +cloud.google.com/go/networkconnectivity v1.5.0 h1:mtIQewrz1ewMU3J0vVkUIJtAkpOqgkz4+UmcreeAm08= cloud.google.com/go/networkconnectivity v1.5.0/go.mod h1:3GzqJx7uhtlM3kln0+x5wyFvuVH1pIBJjhCpjzSt75o= +cloud.google.com/go/networksecurity v0.6.0 h1:qDEX/3sipg9dS5JYsAY+YvgTjPR63cozzAWop8oZS94= cloud.google.com/go/networksecurity v0.6.0/go.mod h1:Q5fjhTr9WMI5mbpRYEbiexTzROf7ZbDzvzCrNl14nyU= +cloud.google.com/go/notebooks v1.3.0 h1:YfPI4pOYQDcqJ+thM2cGtR9oRoRv42vRfubSPZnk3DI= cloud.google.com/go/notebooks v1.3.0/go.mod h1:bFR5lj07DtCPC7YAAJ//vHskFBxA5JzYlH68kXVdk34= +cloud.google.com/go/osconfig v1.8.0 h1:fkFlXCxkUt3tE8LYtF6CipuPbC/HIrciwDTjFpsTf88= cloud.google.com/go/osconfig v1.8.0/go.mod h1:EQqZLu5w5XA7eKizepumcvWx+m8mJUhEwiPqWiZeEdg= +cloud.google.com/go/oslogin v1.5.0 h1:/7sVaMdtqSm6AjxW8KzoM6UKawkg3REr0XJ1zKtidpc= cloud.google.com/go/oslogin v1.5.0/go.mod h1:D260Qj11W2qx/HVF29zBg+0fd6YCSjSqLUkY/qEenQU= +cloud.google.com/go/phishingprotection v0.6.0 h1:OrwHLSRSZyaiOt3tnY33dsKSedxbMzsXvqB21okItNQ= cloud.google.com/go/phishingprotection v0.6.0/go.mod h1:9Y3LBLgy0kDTcYET8ZH3bq/7qni15yVUoAxiFxnlSUA= +cloud.google.com/go/privatecatalog v0.6.0 h1:Vz86uiHCtNGm1DeC32HeG2VXmOq5JRYA3VRPf8ZEcSg= cloud.google.com/go/privatecatalog v0.6.0/go.mod h1:i/fbkZR0hLN29eEWiiwue8Pb+GforiEIBnV9yrRUOKI= cloud.google.com/go/pubsub v1.20.0 h1:QuwfH5BpEIE9T3n0YK3PKlsXi/TmHMu593UpOVlWygI= +cloud.google.com/go/recaptchaenterprise/v2 v2.3.0 h1:BkkI7C0o8CtaHvdDMr5IA+y8pk0Y5wb73C7DHQiAKnw= cloud.google.com/go/recaptchaenterprise/v2 v2.3.0/go.mod h1:O9LwGCjrhGHBQET5CA7dd5NwwNQUErSgEDit1DLNTdo= +cloud.google.com/go/recommendationengine v0.6.0 h1:6w+WxPf2LmUEqX0YyvfCoYb8aBYOcbIV25Vg6R0FLGw= cloud.google.com/go/recommendationengine v0.6.0/go.mod h1:08mq2umu9oIqc7tDy8sx+MNJdLG0fUi3vaSVbztHgJ4= +cloud.google.com/go/recommender v1.6.0 h1:C1tw+Qa/bgm6LoH1wuxYdoyinwKkW/jDJ0GpSJf58cE= cloud.google.com/go/recommender v1.6.0/go.mod h1:+yETpm25mcoiECKh9DEScGzIRyDKpZ0cEhWGo+8bo+c= +cloud.google.com/go/redis v1.8.0 h1:gtPd4pG/Go5mrdGQ4MJXxPHtjxtoWUBkrWLXNV1L2TA= cloud.google.com/go/redis v1.8.0/go.mod h1:Fm2szCDavWzBk2cDKxrkmWBqoCiL1+Ctwq7EyqBCA/A= +cloud.google.com/go/retail v1.9.0 h1:Q3W/JsQupZWaoFxUOugZd1Eq590R+Dk6dhacLK2h7+w= cloud.google.com/go/retail v1.9.0/go.mod h1:g6jb6mKuCS1QKnH/dpu7isX253absFl6iE92nHwlBUY= +cloud.google.com/go/scheduler v1.5.0 h1:Fe1Upic/q4cwqXbInCzgAW35QSerj8JlNwATIxDdfOI= cloud.google.com/go/scheduler v1.5.0/go.mod h1:ri073ym49NW3AfT6DZi21vLZrG07GXr5p3H1KxN5QlI= +cloud.google.com/go/secretmanager v1.3.0 h1:43rHc04zmpiQeqtNKpO5la4bwF5aDhHACZqxQk6D/4c= +cloud.google.com/go/security v1.8.0 h1:linnRc3/gJYDfKbAtNixVQ52+66DpOx5MmCz0NNxal8= cloud.google.com/go/security v1.8.0/go.mod h1:hAQOwgmaHhztFhiQ41CjDODdWP0+AE1B3sX4OFlq+GU= +cloud.google.com/go/securitycenter v1.14.0 h1:hKIggnv2eCAPjsVnFcZbytMOsFOk6p4ut0iAUDoNsNA= cloud.google.com/go/securitycenter v1.14.0/go.mod h1:gZLAhtyKv85n52XYWt6RmeBdydyxfPeTrpToDPw4Auc= +cloud.google.com/go/servicedirectory v1.5.0 h1:QmCWml/qvNOYyiPP4G52srYcsHSLCXuvydJDVLTFSe8= cloud.google.com/go/servicedirectory v1.5.0/go.mod h1:QMKFL0NUySbpZJ1UZs3oFAmdvVxhhxB6eJ/Vlp73dfg= +cloud.google.com/go/speech v1.7.0 h1:bRI2QczZGpcPfuhHr63VOdfyyfYp/43N0wRuBKrd0nQ= cloud.google.com/go/speech v1.7.0/go.mod h1:KptqL+BAQIhMsj1kOP2la5DSEEerPDuOP/2mmkhHhZQ= +cloud.google.com/go/talent v1.2.0 h1:6c4pvu3k2idEhJRZnZ2HdVLWZUuT9fsns2gQtCzRtqA= cloud.google.com/go/talent v1.2.0/go.mod h1:MoNF9bhFQbiJ6eFD3uSsg0uBALw4n4gaCaEjBw9zo8g= +cloud.google.com/go/videointelligence v1.7.0 h1:w56i2xl1jHX2tz6rHXBPHd6xujevhImzbc16Kl+V/zQ= cloud.google.com/go/videointelligence v1.7.0/go.mod h1:k8pI/1wAhjznARtVT9U1llUaFNPh7muw8QyOUpavru4= +cloud.google.com/go/vision/v2 v2.3.0 h1:eEyIDJ5/98UmQrYZ6eQExUT3iHyDjzzPX29UP6x7ZQo= cloud.google.com/go/vision/v2 v2.3.0/go.mod h1:UO61abBx9QRMFkNBbf1D8B1LXdS2cGiiCRx0vSpZoUo= +cloud.google.com/go/webrisk v1.5.0 h1:WdHJmLSAs5bIis/WWO7pIfiRBD1PiWe1OAlPrWeM9Tk= cloud.google.com/go/webrisk v1.5.0/go.mod h1:iPG6fr52Tv7sGk0H6qUFzmL3HHZev1htXuWDEEsqMTg= +cloud.google.com/go/workflows v1.7.0 h1:0MjX5ugKmTdbRG2Vai5aAgNAOe2wzvs/XQwFDSowy9c= cloud.google.com/go/workflows v1.7.0/go.mod h1:JhSrZuVZWuiDfKEFxU0/F1PQjmpnpcoISEXH2bcHC3M= +contrib.go.opencensus.io/exporter/aws v0.0.0-20200617204711-c478e41e60e9 h1:yxE46rQA0QaqPGqN2UnwXvgCrRqtjR1CsGSWVTRjvv4= contrib.go.opencensus.io/exporter/stackdriver v0.13.11 h1:YzmWJ2OT2K3ouXyMm5FmFQPoDs5TfLjx6Xn5x5CLN0I= contrib.go.opencensus.io/exporter/stackdriver v0.13.13 h1:3KLhsPyyFp1pfZPicg8e1VMSeztIyWm+aE+iZQ8b9Kg= +contrib.go.opencensus.io/integrations/ocsql v0.1.7 h1:G3k7C0/W44zcqkpRSFyjU9f6HZkbwIrL//qqnlqWZ60= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9 h1:VpgP7xuJadIUuKccphEpTJnWhS2jkQyMt6Y7pJCD7fY= +github.com/Azure/azure-amqp-common-go/v3 v3.2.2 h1:CJpxNAGxP7UBhDusRUoaOn0uOorQyAYhQYLnNgkRhlY= +github.com/Azure/azure-sdk-for-go v59.3.0+incompatible h1:dPIm0BO4jsMXFcCI/sLTPkBtE7mk8WMuRHA0JeWhlcQ= +github.com/Azure/azure-sdk-for-go/sdk/azcore v0.19.0 h1:lhSJz9RMbJcTgxifR1hUNJnn6CNYtbgEDtQV22/9RBA= +github.com/Azure/azure-sdk-for-go/sdk/azidentity v0.11.0 h1:OYa9vmRX2XC5GXRAzeggG12sF/z5D9Ahtdm9EJ00WN4= +github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0 h1:v9p9TfTbf7AwNb5NYQt7hI41IfPoLFiFkLtb+bmGjT0= +github.com/Azure/azure-service-bus-go v0.11.5 h1:EVMicXGNrSX+rHRCBgm/TRQ4VUZ1m3yAYM/AB2R/SOs= +github.com/Azure/go-amqp v0.16.4 h1:/1oIXrq5zwXLHaoYDliJyiFjJSpJZMWGgtMX9e0/Z30= github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs= github.com/Azure/go-autorest/autorest v0.11.22 h1:bXiQwDjrRmBQOE67bwlvUKAC1EU1yZTPQ38c+bstZws= github.com/Azure/go-autorest/autorest/adal v0.9.17 h1:esOPl2dhcz9P3jqBSJ8tPGEj2EqzPPT6zfyuloiogKY= +github.com/Azure/go-autorest/autorest/azure/auth v0.5.9 h1:Y2CgdzitFDsdMwYMzf9LIZWrrTFysqbRc7b94XVVJ78= +github.com/Azure/go-autorest/autorest/azure/cli v0.4.2 h1:dMOmEJfkLKW/7JsokJqkyoYSgmR08hi9KrhjZb+JALY= github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw= +github.com/Azure/go-autorest/autorest/mocks v0.4.1 h1:K0laFcLE6VLTOwNgSxaGbUcLPuGXlNkbVvq4cW4nIHk= +github.com/Azure/go-autorest/autorest/to v0.4.0 h1:oXVqrxakqqV1UZdSazDOPOLvOIz+XA683u8EctwboHk= +github.com/Azure/go-autorest/autorest/validation v0.3.1 h1:AgyqjAd94fwNAoTjl/WQXg4VvFeRFpO+UhNyRXqF1ac= github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg= github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= +github.com/GoogleCloudPlatform/cloudsql-proxy v1.29.0 h1:YNu23BtH0PKF+fg3ykSorCp6jSTjcEtfnYLzbmcjVRA= github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc= +github.com/Microsoft/go-winio v0.6.0 h1:slsWYD/zyx7lCXoZVlvQrj0hPTM1HI4+v1sIda2yDvg= +github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= +github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= +github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= +github.com/antihax/optional v1.0.0 h1:xK2lYat7ZLaVVcIuj82J8kIro4V6kDe0AUDFboUCwcg= +github.com/armon/go-metrics v0.3.10 h1:FR+drcQStOe+32sYyJYyZ7FIdgoGGBnwLl+flodp8Uo= +github.com/aws/aws-sdk-go-v2/service/kms v1.16.3 h1:nUP29LA4GZZPihNSo5ZcF4Rl73u+bN5IBRnrQA0jFK4= +github.com/aws/aws-sdk-go-v2/service/secretsmanager v1.15.4 h1:EmIEXOjAdXtxa2OGM1VAajZV/i06Q8qd4kBpJd9/p1k= +github.com/aws/aws-sdk-go-v2/service/sns v1.17.4 h1:7TdmoJJBwLFyakXjfrGztejwY5Ie1JEto7YFfznCmAw= +github.com/aws/aws-sdk-go-v2/service/sqs v1.18.3 h1:uHjK81fESbGy2Y9lspub1+C6VN5W2UXTDo2A/Pm4G0U= +github.com/aws/aws-sdk-go-v2/service/ssm v1.24.1 h1:zc1YLcknvxdW/i1MuJKmEnFB2TNkOfguuQaGRvJXPng= github.com/caarlos0/env/v6 v6.9.1 h1:zOkkjM0F6ltnQ5eBX6IPI41UP/KDGEK7rRPwGCNos8k= github.com/caarlos0/env/v6 v6.10.0 h1:lA7sxiGArZ2KkiqpOQNf8ERBRWI+v8MWIH+eGjSN22I= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= +github.com/chzyer/logex v1.1.10 h1:Swpa1K6QvQznwJRcfTfQJmTE72DqScAa40E+fbHEXEE= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e h1:fY5BOSpyZCqRo5OhCuC+XN+r/bBCmeuuJtjz+bCNIf8= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1 h1:q763qf9huN11kDQavWsoZXJNW3xEE4JJyHa5Q25/sd8= +github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI= +github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4 h1:hzAQntlaYRkVSFEfj9OTWlVV1H155FMD8BTKktLv0QI= +github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1 h1:zH8ljVhhq7yC0MIeUL/IviMtY8hx2mK8cN9wEYb8ggw= +github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I= github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= github.com/containerd/stargz-snapshotter/estargz v0.12.1 h1:+7nYmHJb0tEkcRaAW+MHqoKaJYZmkikupxCqVtmPuY0= github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY= +github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM= +github.com/coreos/go-systemd v0.0.0-20190719114852-fd7a80b32e1f h1:JOrtw2xFKzlg+cbHpyrpLDmnN1HqhBfnX7WDiW7eG2c= +github.com/coreos/go-systemd/v22 v22.3.2 h1:D9/bQk5vlXQFZ6Kwuu6zaiXJ9oTPe68++AzAJc1DzSI= +github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w= +github.com/creack/pty v1.1.9 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w= +github.com/cristalhq/acmd v0.8.1 h1:mtFp/cbeJNY5jokF9zPz5mRllGHropRrOkOVxeGS6FI= +github.com/denisenkom/go-mssqldb v0.12.0 h1:VtrkII767ttSPNRfFekePK3sctr+joXgO58stqQbtUA= +github.com/devigned/tab v0.1.1 h1:3mD6Kb1mUOYeLpJvTVSDwSg5ZsfSxfvxGRTxRsJsITA= +github.com/dimchansky/utfbom v1.1.1 h1:vV6w1AhK4VMnhBno/TPVCoK9U/LP0PkLCS9tbxHdi/U= +github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI= github.com/docker/cli v20.10.20+incompatible h1:lWQbHSHUFs7KraSN2jOJK7zbMS2jNCHI4mt4xUFUVQ4= github.com/docker/distribution v2.8.1+incompatible h1:Q50tZOPR6T/hjNsyc9g8/syEs6bk8XXApsHjKukMl68= github.com/docker/docker v20.10.20+incompatible h1:kH9tx6XO+359d+iAkumyKDc5Q1kOwPuAUaeri48nD6E= github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A= +github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= +github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1 h1:xvqufLtNVwAhN8NMyWklVgxnWohi+wtMGQMhtxexlm0= +github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A= +github.com/form3tech-oss/jwt-go v3.2.2+incompatible h1:TcekIExNqud5crz4xD2pavyTgWiPvpYe4Xau31I0PRk= +github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-gonic/gin v1.7.3 h1:aMBzLJ/GMEYmv1UWs2FFTcPISLrQH2mRgL9Glz8xows= +github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4= +github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34= +github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1 h1:QbL/5oDUmRBzO9/Z7Seo6zf912W/a6Sr4Eu0G/3Jho0= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4 h1:WtGNWLvXpe6ZudgnXrq0barxBImvnnJoMEhXAzcbM0I= +github.com/go-ini/ini v1.25.4 h1:Mujh4R/dH6YL8bxuISne3xX2+qcQ9p0IxKAP6ExWoUo= +github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= +github.com/go-kit/log v0.1.0 h1:DGJh0Sm43HbOeYDNnVZFl8BvcYVvjD5bqYJvp0REbwQ= +github.com/go-logfmt/logfmt v0.5.0 h1:TrB8swr/68K7m9CcGut2g3UOihhbcbiMAYiuTXdEih4= +github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY= +github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= +github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q= +github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no= +github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee h1:s+21KNqlpePfkah2I+gwHF8xmJWRjooY+5248k6m4A0= +github.com/gobwas/pool v0.2.0 h1:QEmUOlnSjWtnpRGHF3SauEiOsy82Cup83Vf2LcMlnc8= +github.com/gobwas/ws v1.0.2 h1:CoAavW/wd/kulfZmSIBt6p24n4j7tHgNVCjsfHVNUbo= +github.com/godbus/dbus/v5 v5.0.4 h1:9349emZab16e7zQvpmsbtjc18ykshndd8y2PG3sgJbA= +github.com/gofrs/uuid v4.0.0+incompatible h1:1SD/1F5pU8p29ybwgQSwpQk+mwdRrXCYuPhW6m+TnJw= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY= +github.com/golang-sql/sqlexp v0.0.0-20170517235910-f1bb20e5a188 h1:+eHOFJl1BaXrQxKX+T06f78590z4qA2ZzBTqahsKSE4= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc= +github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= +github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo= github.com/google/go-containerregistry v0.12.1 h1:W1mzdNUTx4Zla4JaixCRLhORcR7G6KxE5hHl5fkPsp8= +github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= +github.com/google/renameio v0.1.0 h1:GOZbcHa3HfsPKPlmyPyN2KEohoMXOhdMbHrvbpl2QaA= +github.com/google/subcommands v1.0.1 h1:/eqq+otEXm5vhfBrbREPCSVQbvofip6kIz+mX5TUH7k= github.com/googleapis/gax-go/v2 v2.5.1/go.mod h1:h6B0KMMFNtI2ddbGJn3T3ZbwkeT6yqEF02fYlzkUCyo= +github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= +github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8 h1:tlyzajkF3030q6M8SvmJSemC9DTHL/xaMa18b65+JM4= +github.com/gookit/color v1.5.1 h1:Vjg2VEcdHpwq+oY63s/ksHrgJYCTo0bwWvmmYWdE9fQ= +github.com/gorilla/websocket v1.4.1 h1:q7AeDBpnBk8AogcD4DSag/Ukw/KV+YhzLj2bP5HvKCM= +github.com/grpc-ecosystem/grpc-gateway v1.16.0 h1:gmcG1KaJ57LophUzW0Hy8NmPhnMZb4M0+kPpLofRdBo= github.com/h2non/filetype v1.1.3 h1:FKkx9QbD7HR/zjK1Ia5XiBsq9zdLi5Kf3zGyFTAFkGg= +github.com/hanwen/go-fuse v1.0.0 h1:GxS9Zrn6c35/BnfiVsZVWmsG803xwE7eVRDvcf/BEVc= +github.com/hanwen/go-fuse/v2 v2.1.0 h1:+32ffteETaLYClUj0a3aHjZ1hOPxxaNEHiZiujuDaek= +github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-retryablehttp v0.7.1 h1:sUiuQAnLlbvmExtFQs72iFW/HXeUn8Z1aJLQ4LJJbTQ= +github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/serf v0.9.7 h1:hkdgbqizGQHuU5IPqYM1JdSMV8nKfpuOnZYXssk9muY= +github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639 h1:mV02weKRL81bEnm8A0HT1/CAelMQDBuQIfLw8n+d6xI= +github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/jackc/chunkreader v1.0.0 h1:4s39bBR8ByfqH+DKm8rQA3E1LHZWB9XWcrz8fqaZbe0= +github.com/jackc/chunkreader/v2 v2.0.1 h1:i+RDz65UE+mmpjTfyz0MoVTnzeYxroil2G82ki7MGG8= +github.com/jackc/pgconn v1.11.0 h1:HiHArx4yFbwl91X3qqIHtUFoiIfLNJXCQRsnzkiwwaQ= +github.com/jackc/pgio v1.0.0 h1:g12B9UwVnzGhueNavwioyEEpAmqMe1E/BN9ES+8ovkE= +github.com/jackc/pgmock v0.0.0-20210724152146-4ad1a8207f65 h1:DadwsjnMwFjfWc9y5Wi/+Zz7xoE5ALHsRQlOctkOiHc= +github.com/jackc/pgpassfile v1.0.0 h1:/6Hmqy13Ss2zCq62VdNG8tM1wchn8zjSGOBJ6icpsIM= +github.com/jackc/pgproto3 v1.1.0 h1:FYYE4yRw+AgI8wXIinMlNjBbp/UitDJwfj5LqqewP1A= +github.com/jackc/pgproto3/v2 v2.2.0 h1:r7JypeP2D3onoQTCxWdTpCtJ4D+qpKr0TxvoyMhZ5ns= +github.com/jackc/pgservicefile v0.0.0-20200714003250-2b9c44734f2b h1:C8S2+VttkHFdOOCXJe+YGfa4vHYwlt4Zx+IVXQ97jYg= +github.com/jackc/pgtype v1.10.0 h1:ILnBWrRMSXGczYvmkYD6PsYyVFUNLTnIUJHHDLmqk38= +github.com/jackc/pgx/v4 v4.15.0 h1:B7dTkXsdILD3MF987WGGCcg+tvLW6bZJdEcqVFeU//w= +github.com/jackc/puddle v1.2.1 h1:gI8os0wpRXFd4FiAY2dWiqRK037tjj3t7rKFeO4X5iw= +github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= +github.com/jmoiron/sqlx v1.2.0 h1:41Ip0zITnmWNR/vHV+S4m+VoUivnWY5E4OJfLZjCJMA= +github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= +github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o= github.com/jszwec/csvutil v1.6.0 h1:QORXquCT0t8nUKD7utAD4HDmQMgG0Ir9WieZXzpa7ms= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck= github.com/klauspost/compress v1.15.11 h1:Lcadnb3RKGin4FYM/orgq0qde+nc15E5Cbqg4B9Sx9c= +github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= +github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= +github.com/kr/pty v1.1.8 h1:AkaSdXYQOWeaO3neb8EM634ahkXXe3jYbVh/F9lq+GI= +github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348 h1:MtvEpTB6LX3vkb4ax0b5D2DHbNAUsen0Gx5wZoq3lV4= +github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y= +github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs= +github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4= +github.com/magefile/mage v1.14.0 h1:6QDX3g6z1YvJ4olPhT1wksUcSa/V0a1B+pJb73fBjyo= github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-sqlite3 v1.9.0 h1:pDRiWfl+++eC2FEFRy6jXmQlvp4Yh3z1MJKg4UeYM/4= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mcuadros/go-jsonschema-generator v0.0.0-20200330054847-ba7a369d4303 h1:mc6Th1b2xkPDUHTIUynE0LMJUgPEJdIDUjBLvj8yprs= +github.com/mgechev/dots v0.0.0-20210922191527-e955255bf517 h1:zpIH83+oKzcpryru8ceC6BxnoG8TBrhgAvRg8obzup0= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= github.com/moby/buildkit v0.8.3 h1:vFlwUQ6BZE1loZ8zoZH3fYgmA1djFCS3DrOhCVU6ZZE= github.com/moby/buildkit v0.10.3 h1:/dGykD8FW+H4p++q5+KqKEo6gAkYKyBQHdawdjVwVAU= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modocache/gover v0.0.0-20171022184752-b58185e213c5 h1:8Q0qkMVC/MmWkpIdlvZgcv2o2jrlF6zqVOh7W5YHdMA= +github.com/mozilla/tls-observatory v0.0.0-20210609171429-7bc42856d2e5 h1:0KqC6/sLy7fDpBdybhVkkv4Yz+PmB7c9Dz9z3dLW804= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/image-spec v1.1.0-rc2 h1:2zx/Stx4Wc5pIPDvIxHXvXtQFW/7XWJGmnM7r3wg034= +github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= +github.com/otiai10/mint v1.3.1 h1:BCmzIS3n71sGfHB5NMNDB3lHYPz8fWSkCAErHed//qc= +github.com/pkg/browser v0.0.0-20180916011732-0a3d74bf9ce4 h1:49lOXmGaUpV9Fz3gd7TFZY106KVlPVa5jcYD1gaQf98= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= +github.com/pkg/sftp v1.13.1 h1:I2qBYMChEhIjOgazfJmV3/mZM256btk6wkCDRmW7JYs= +github.com/power-devops/perfstat v0.0.0-20210106213030-5aafc221ea8c h1:ncq/mPwQF4JjgDlrVEn3C11VoGHZN7m8qihwgMEtzYw= github.com/prometheus/client_golang v1.12.2 h1:51L9cDoUHVrXx4zWYlcLQIZ+d+VXHgqnYKkIuq4g/34= github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= +github.com/quasilyte/go-ruleguard/dsl v0.3.21 h1:vNkC6fC6qMLzCOGbnIHOd5ixUGgTbp3Z4fGnUgULlDA= +github.com/quasilyte/go-ruleguard/rules v0.0.0-20211022131956-028d6511ab71 h1:CNooiryw5aisadVfzneSZPswRWvnVW8hF1bS/vo8ReI= +github.com/remyoudompheng/go-dbus v0.0.0-20121104212943-b7232d34b1d5 h1:CvqZS4QYHBRvx7AeFdimd16HCbLlYsvQMcKDACpJW/c= +github.com/remyoudompheng/go-liblzma v0.0.0-20190506200333-81bf2d431b96 h1:J8J/cgLDRuqXJnwIrRDBvtl+LLsdg7De74znW/BRRq4= +github.com/remyoudompheng/go-misc v0.0.0-20190427085024-2d6ac652a50e h1:eTWZyPUnHcuGRDiryS/l2I7FfKjbU3IBx3IjqHPxuKU= github.com/rhysd/actionlint v1.6.11 h1:8aD7ozc43RbnKwUmFvRtfW0LTW6f13MTXFDlf+0PNAc= github.com/rhysd/actionlint v1.6.15 h1:IxQIp10aVce77jNnoHye7NFka8/7CRBSvKXoMRGryXM= github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/robfig/cron v1.2.0 h1:ZjScXvvxeQ63Dbyxy76Fj3AT3Ut0aKsyd2/tl3DTMuQ= +github.com/rogpeppe/fastuuid v1.2.0 h1:Ppwyp6VYCF1nvBTXL3trRso7mXMlRrw9ooo375wvi2s= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/xid v1.2.1 h1:mhH9Nq+C1fY2l1XIpgxIiUOfNpRBYH1kKcr+qfKgjRc= +github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY= +github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= +github.com/sagikazarmark/crypt v0.6.0 h1:REOEXCs/NFY/1jOCEouMuT4zEniE5YoXbvpC5X/TLF8= +github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= +github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0= +github.com/shirou/gopsutil/v3 v3.22.9 h1:yibtJhIVEMcdw+tCTbOPiF1VcsuDeTE4utJ8Dm4c5eA= +github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e h1:MZM7FHLqUHYI0Y/mQAt3d2aYa0SiNms/hFqC9qJYolM= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041 h1:llrF3Fs4018ePo4+G/HV/uQUqEI1HMDjCeOf2V6puPc= +github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72 h1:qLC7fQah7D6K1B0ujays3HV9gkFtllcxhzImRR7ArPQ= github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/tklauser/go-sysconf v0.3.10 h1:IJ1AZGZRWbY8T5Vfk04D9WOA5WSejdflXxP03OUqALw= +github.com/tklauser/numcpus v0.4.0 h1:E53Dm1HjH1/R2/aoCtXtPgzmElmn51aOkhCFSuZq//o= +github.com/ugorji/go v1.1.7 h1:/68gy2h+1mWMrwZFeD1kQialdSzAb432dtpeJ42ovdo= +github.com/ugorji/go/codec v1.1.7 h1:2SvQaVZ1ouYrrKKwoSk2pzd4A9evlKJb9oTL+OaLUSs= +github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw= +github.com/valyala/quicktemplate v1.7.0 h1:LUPTJmlVcb46OOUY3IeD9DojFpAVbsG+5WFTcjMJzCM= github.com/vbatts/tar-split v0.11.2 h1:Via6XqJr0hceW4wff3QRzD5gAk/tatMw/4ZA7cTlIME= +github.com/xanzy/go-gitlab v0.74.0 h1:Ha1cokbjn0PXy6B19t3W324dwM4AOT52fuHr7nERPrc= +github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f h1:mvXjJIHRZyhNuGassLTcXTwjiWq7NmjdavZsUnmFybQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= +github.com/yusufpapurcu/wmi v1.2.2 h1:KBNDSne4vP5mbSWnJbO+51IMOXJB67QiYCSBrubbPRg= +github.com/zenazn/goji v0.9.0 h1:RSQQAbXGArQ0dIDEq+PI6WqN6if+5KHu6x2Cx/GXLTQ= +go.etcd.io/etcd/api/v3 v3.5.4 h1:OHVyt3TopwtUQ2GKdd5wu3PmmipR4FTwCqoEjSyRdIc= +go.etcd.io/etcd/client/pkg/v3 v3.5.4 h1:lrneYvz923dvC14R54XcA7FXoZ3mlGZAgmwhfm7HqOg= +go.etcd.io/etcd/client/v2 v2.305.4 h1:Dcx3/MYyfKcPNLpR4VVQUP5KgYrBeJtktBwEKkw08Ao= +go.etcd.io/etcd/client/v3 v3.5.4 h1:p83BUL3tAYS0OT/r0qglgc3M1JjhM0diV8DSWAhVXv4= +go.opentelemetry.io/proto/otlp v0.7.0 h1:rwOQPCuKAKmwGKq2aVNnYIibI6wnV7EvzgfTCzcdGg8= +go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= go.uber.org/zap v1.21.0 h1:WefMeulhovoZ2sYXz7st6K0sLj7bBhpiFaud4r4zST8= golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa h1:zuSxTR4o9y82ebqCUJYNGJbGPo6sKVl54f/TVDObg1c= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 h1:VLliZ0d+/avPrXXH+OakdXhpJuEoBZuwh1m2j7U6Iug= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028 h1:4+4C/Iv2U4fMZBiMCc98MG1In4gJY5YRhtpDNeDeHWs= golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= @@ -124,7 +364,9 @@ golang.org/x/oauth2 v0.0.0-20221006150949-b44042a4b9c1/go.mod h1:h4gKUeWbJ4rQPri golang.org/x/oauth2 v0.0.0-20221014153046-6fdb5e3db783/go.mod h1:h4gKUeWbJ4rQPri7E0u6Gs4e9Ri2zaLxzw5DI5XGrYg= golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM= @@ -142,8 +384,17 @@ google.golang.org/genproto v0.0.0-20221010155953-15ba04fc1c0e/go.mod h1:3526vdqw google.golang.org/genproto v0.0.0-20221014173430-6e2ab493f96b/go.mod h1:1vXfmgAz9N9Jx0QA82PqRVauvCz1SGSz739p0f183jM= google.golang.org/grpc v1.49.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= google.golang.org/grpc v1.50.0/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0 h1:M1YKkFIboKNieVO5DLUEVzQfGwJD30Nv2jfUgzb5UcE= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= +gopkg.in/errgo.v2 v2.1.0 h1:0vLT13EuvQ0hNvakwLuFZ/jYrLp5F3kcWHXdRggjCE8= +gopkg.in/inconshreveable/log15.v2 v2.0.0-20180818164646-67afb5ed74ec h1:RlWgLqCMMIYYEVcAR5MDsuHlVkaIPDAF+5Dehzg8L5A= +gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= mvdan.cc/sh/v3 v3.4.3 h1:zbuKH7YH9cqU6PGajhFFXZY7dhPXcDr55iN/cUAqpuw= mvdan.cc/sh/v3 v3.5.1 h1:hmP3UOw4f+EYexsJjFxvU38+kn+V/s2CclXHanIBkmQ= +nhooyr.io/websocket v1.8.7 h1:usjR2uOr/zjjkVMy0lW+PPohFok7PCow5sDjLgX4P4g= +rsc.io/binaryregexp v0.2.0 h1:HfqmD5MEmC0zvwBuF187nq9mdnXjXsSivRiXN7SmRkE= +rsc.io/quote/v3 v3.1.0 h1:9JKUTTIUgS6kzR9mK1YuGKv6Nl+DijDNIc0ghT58FaY= +rsc.io/sampler v1.3.0 h1:7uVkIFmeBqHfdjD+gZwtXXI+RODJ2Wc4O7MPEh/QiW4= sigs.k8s.io/release-utils v0.6.0 h1:wJDuzWJqPH4a5FAxAXE2aBvbB6UMIW7iYMhsKnIMQkA= diff --git a/tools/tools.go b/tools/tools.go index 043e922c..3c3ca2c2 100644 --- a/tools/tools.go +++ b/tools/tools.go @@ -17,4 +17,5 @@ package main // This set of imports is used to ensure `go mod tidy` does not remove them. import ( _ "github.com/golangci/golangci-lint/cmd/golangci-lint" + _ "mvdan.cc/gofumpt" ) From c6e44370f7edf655d418fd988be3265717ccf36b Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Sun, 4 Dec 2022 20:54:34 -0600 Subject: [PATCH 147/172] Unit tests - internal/githubapi/errors (#257) * Unit tests - internal/githubapi/errors - Unit tests for errors - Refactored errors Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Added License Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Refactored based on code review Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Added extra test case Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- internal/githubapi/errors.go | 4 - internal/githubapi/errors_test.go | 210 ++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+), 4 deletions(-) create mode 100644 internal/githubapi/errors_test.go diff --git a/internal/githubapi/errors.go b/internal/githubapi/errors.go index f5938ca8..1b87df98 100644 --- a/internal/githubapi/errors.go +++ b/internal/githubapi/errors.go @@ -95,10 +95,6 @@ func (e *GraphQLErrors) Errors() []GraphQLError { // Is implements the errors.Is interface. func (e *GraphQLErrors) Is(target error) bool { - if target == e { - // Identity test is always true. - return true - } if target == ErrGraphQLNotFound { return len(e.errors) == 1 && e.HasType(gitHubGraphQLNotFoundType) } diff --git a/internal/githubapi/errors_test.go b/internal/githubapi/errors_test.go new file mode 100644 index 00000000..0cdfcde8 --- /dev/null +++ b/internal/githubapi/errors_test.go @@ -0,0 +1,210 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package githubapi + +import ( + "errors" + "net/http" + "testing" + + "github.com/google/go-github/v47/github" +) + +func TestErrorResponseStatusCode(t *testing.T) { + tests := []struct { //nolint:govet + name string + err error + want int + }{ + { + name: "nil error", + want: 0, + }, + { + name: "non-nil error that is not an ErrorResponse", + err: errors.New("some error"), + want: 0, + }, + { + name: "error that is an ErrorResponse", + err: &github.ErrorResponse{ + Response: &http.Response{ + StatusCode: 404, + }, + }, + want: 404, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := ErrorResponseStatusCode(test.err); got != test.want { + t.Errorf("ErrorResponseStatusCode() = %v, want %v", got, test.want) + } + }) + } +} + +func TestGraphQLErrors_Error(t *testing.T) { + tests := []struct { //nolint:govet + name string + errors []GraphQLError + want string + wantPanic bool + }{ + { + name: "zero errors", + errors: []GraphQLError{}, + wantPanic: true, + }, + { + name: "one error", + errors: []GraphQLError{ + {Message: "one"}, + }, + want: "one", + }, + { + name: "more than one error", + errors: []GraphQLError{ + {Message: "one"}, + {Message: "two"}, + {Message: "three"}, + }, + want: "3 GraphQL errors", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + defer func() { + r := recover() + if r != nil && !test.wantPanic { + t.Fatalf("Error() panic: %v, want no panic", r) + } + }() + + e := &GraphQLErrors{test.errors} + + if got := e.Error(); got != test.want { + t.Errorf("Error() = %v, want %v", got, test.want) + } + }) + } +} + +func TestGraphQLErrors_HasType(t *testing.T) { + tests := []struct { //nolint:govet + name string + errors []GraphQLError + t string + want bool + }{ + { + name: "type is equal to t", + errors: []GraphQLError{ + {Type: "NOT_FOUND"}, + }, + t: "NOT_FOUND", + want: true, + }, + { + name: "type without NOT_FOUND", + errors: []GraphQLError{}, + t: "NOT_FOUND", + want: false, + }, + { + name: "type multiple type fields not set to t", + errors: []GraphQLError{ + {Type: "random_1"}, + {Type: "random_2"}, + {Type: "random_3"}, + }, + t: "NOT_FOUND", + want: false, + }, + { + name: "type is not equal to t", + errors: []GraphQLError{ + {Type: "NOT_FOUND"}, + }, + t: "invalid type", + want: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + e := &GraphQLErrors{ + errors: test.errors, + } + if got := e.HasType(test.t); got != test.want { + t.Errorf("HasType() = %v, want %v", got, test.want) + } + }) + } +} + +func TestGraphQLErrors_Is(t *testing.T) { + tests := []struct { //nolint:govet + name string + errors []GraphQLError + target error + want bool + }{ + { + name: "target equals ErrGraphQLNotFound and returns true", + errors: []GraphQLError{ + {Message: "one", Type: "NOT_FOUND"}, + }, + target: ErrGraphQLNotFound, + want: true, + }, + { + name: "target equals ErrGraphQLNotFound and returns false", + errors: []GraphQLError{ + {Message: "one"}, + }, + target: ErrGraphQLNotFound, + want: false, + }, + { + name: "regular testcase", + errors: []GraphQLError{ + {Message: "one"}, + }, + target: errors.New("some error"), + want: false, + }, + { + name: "multiple errors with only one having the error type as 'NOT_FOUND'", + errors: []GraphQLError{ + {Message: "one"}, + {Message: "two", Type: "NOT_FOUND"}, + {Message: "three"}, + }, + target: ErrGraphQLNotFound, + want: false, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + e := &GraphQLErrors{ + errors: test.errors, + } + if got := e.Is(test.target); got != test.want { + t.Errorf("Is() = %v, want %v", got, test.want) + } + }) + } +} From 0cc7357a01691d4a5873e1886e4ab4ae984e9da7 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 5 Dec 2022 14:54:02 +1100 Subject: [PATCH 148/172] Update contact for the code of conduct. (#273) Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- CODE_OF_CONDUCT.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f3921f21..23c638c8 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -60,7 +60,7 @@ representative at an online or offline event. Instances of abusive, harassing, or otherwise unacceptable behavior may be reported to the community leaders responsible for enforcement at -[INSERT CONTACT METHOD]. +conduct@openssf.org. All complaints will be reviewed and investigated promptly and fairly. All community leaders are obligated to respect the privacy and security of the From 0fa60ba04f663ac9c85c70a5059d2f800c7e293b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 5 Dec 2022 16:54:25 +1100 Subject: [PATCH 149/172] Bump actions/setup-go from 3.3.1 to 3.4.0 (#272) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3.3.1 to 3.4.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/c4a742cab115ed795e34d4513e2cf7d472deb55f...d0a58c1c4d2b25278816e339b944508c875f3613) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 18061cf3..19d15751 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - - uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f + - uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 with: go-version: 1.19 - name: Run tests @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - - uses: actions/setup-go@c4a742cab115ed795e34d4513e2cf7d472deb55f + - uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 with: go-version: 1.19 - name: golangci-lint From 95942e03caa6efc1616c47e8f1c446c9fb256914 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Thu, 8 Dec 2022 16:38:52 -0600 Subject: [PATCH 150/172] Fixed Bug in registry/EmptySets (#275) * Removed Dead Code from registry/EmptySets - The exists map is always empty so it can't contain anything. Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed bug Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> --- internal/collector/registry.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/collector/registry.go b/internal/collector/registry.go index b71e6322..a41766bd 100644 --- a/internal/collector/registry.go +++ b/internal/collector/registry.go @@ -98,6 +98,7 @@ func (r *registry) EmptySets() []signal.Set { continue } ss = append(ss, c.EmptySet()) + exists[c.EmptySet().Namespace()] = empty{} } return ss } From 27ad7d2f529ff28e8cc22ab3c59883f65081071c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 22 Dec 2022 16:50:54 +1100 Subject: [PATCH 151/172] Bump ossf/scorecard-action from 2.0.6 to 2.1.2 (#290) Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.0.6 to 2.1.2. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/99c53751e09b9529366343771cc321ec74e9bd3d...e38b1902ae4f44df626f11ba0734b14fb91f8f86) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index d7c96d5b..c5f851e4 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -21,7 +21,7 @@ jobs: - name: "Checkout code" uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - name: "Run analysis" - uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # v2.0.0-alpha.2 + uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.0.0-alpha.2 with: results_file: results.sarif results_format: sarif From 8a23fdf0e7a056731bb71f7f57c26f10a73ad8a6 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Tue, 10 Jan 2023 17:19:37 -0600 Subject: [PATCH 152/172] Unit tests - scorer/input (#255) * Unit tests - scorer/input - Added unit tests for scorer/input Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Changed formating Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated Based on Code Review Comments Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- internal/scorer/algorithm/input_test.go | 185 ++++++++++++++++++++++++ 1 file changed, 185 insertions(+) create mode 100644 internal/scorer/algorithm/input_test.go diff --git a/internal/scorer/algorithm/input_test.go b/internal/scorer/algorithm/input_test.go new file mode 100644 index 00000000..bf6b19fd --- /dev/null +++ b/internal/scorer/algorithm/input_test.go @@ -0,0 +1,185 @@ +package algorithm + +import "testing" + +func TestBoundsApply(t *testing.T) { + tests := []struct { + name string + b Bounds + v float64 + want float64 + }{ + { + "regular test", + Bounds{ + 0, + 10, + false, + }, + 7, + 7, + }, + { + "SmallerIsBetter equals true", + Bounds{ + 0, + 10, + true, + }, + 7, + 3, + }, + { + "lower is not 0", + Bounds{ + 40, + 80, + false, + }, + 50, + 10, + }, + { + "upper bound > lower bound", // should this test work? + Bounds{ + 40, + 20, + false, + }, + 30, + 0, + }, + { + "upper bound == lower bound", // similar question as above, should this work? + Bounds{ + 40, + 40, + false, + }, + 40, + 0, + }, + { + "upper bound == lower bound and SmallerIsBetter is true", // same question as above + Bounds{ + 40, + 40, + true, + }, + 40, + 0, + }, + { + "v is negative", // can v be negative? + Bounds{ + 0, + 10, + false, + }, + -10, + 0, + }, + { + "v is lower than lower bound and SmallerIsBetter is true", + Bounds{ + 20, + 30, + true, + }, + 15, + 10, + }, + { + "v is greater than upper bound and SmallerIsBetter is true", + Bounds{ + 0, + 10, + true, + }, + 20, + 0, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := test.b.Apply(test.v); got != test.want { + t.Errorf("Apply(%v) = %v, want %v", test.v, got, test.want) + } + }) + } +} + +func TestInputValue(t *testing.T) { + type fields struct { + Source Value + Bounds *Bounds + Distribution *Distribution + Tags []string + Weight float64 + } + type want struct { + val float64 + ok bool + } + + //nolint:govet + tests := []struct { + name string + input fields + fields map[string]float64 + want want + }{ + { + name: "regular test", + input: fields{ + Source: Field("test"), + Distribution: LookupDistribution("linear"), + }, + fields: map[string]float64{"test": 10}, + + want: want{10, true}, + }, + { + name: "invalid Field", + input: fields{ + Source: Field("test2"), + }, + fields: map[string]float64{"test": 10}, + + want: want{0, false}, + }, + { + name: "bounds not equal to nil", + input: fields{ + Source: Field("test"), + Bounds: &Bounds{ + Lower: 0, + Upper: 10, + SmallerIsBetter: false, + }, + Distribution: LookupDistribution("linear"), + }, + fields: map[string]float64{"test": 5}, + + want: want{0.5, true}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + i := &Input{ + Source: test.input.Source, + Bounds: test.input.Bounds, + Distribution: test.input.Distribution, + Tags: test.input.Tags, + Weight: test.input.Weight, + } + wantVal, wantBool := i.Value(test.fields) + if wantVal != test.want.val { + t.Errorf("Value() wantVal = %v, want %v", wantVal, test.want.val) + } + if wantBool != test.want.ok { + t.Errorf("Value() wantBool = %v, want %v", wantBool, test.want.ok) + } + }) + } +} From 2579b0727789427c483b632ed335d58edeaafdb6 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Tue, 10 Jan 2023 17:34:38 -0600 Subject: [PATCH 153/172] Unit tests - internal/scorer/value (#258) * Unit tests - internal/scorer/value - Added unit tests for internal/scorer/value Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated based on code review comments Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Renamed function Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- internal/scorer/algorithm/value_test.go | 110 ++++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 internal/scorer/algorithm/value_test.go diff --git a/internal/scorer/algorithm/value_test.go b/internal/scorer/algorithm/value_test.go new file mode 100644 index 00000000..a955fe60 --- /dev/null +++ b/internal/scorer/algorithm/value_test.go @@ -0,0 +1,110 @@ +// Copyright 2022 Criticality Score 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 +// +// 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. + +package algorithm + +import ( + "testing" +) + +func TestCondition(t *testing.T) { + tests := []struct { //nolint:govet + name string + f Field + fields map[string]float64 + existsWant bool // for ExistsCondition() + notWant bool // for NotCondition() + }{ + { + name: "exists", + f: Field("a"), + fields: map[string]float64{"a": 1}, + existsWant: true, + notWant: false, + }, + { + name: "not exists", + f: Field("a"), + fields: map[string]float64{"b": 1}, + existsWant: false, + notWant: true, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got := ExistsCondition(test.f) + + if got(test.fields) != test.existsWant { + t.Errorf("ExistsCondition() = %v, wantVal %v", got(test.fields), test.existsWant) + } + + got = NotCondition(got) + + if got(test.fields) != test.notWant { + t.Errorf("NotCondition() = %v, wantVal %v", got(test.fields), test.notWant) + } + }) + } +} + +func TestValue(t *testing.T) { + type want struct { + value float64 + exists bool + } + tests := []struct { //nolint:govet + name string + Condition Condition + value Field + fields map[string]float64 + w want + }{ + { + name: "exists", + Condition: ExistsCondition(Field("a")), + value: Field("a"), + fields: map[string]float64{"a": 1}, + w: want{1, true}, + }, + { + name: "not exists", + Condition: ExistsCondition(Field("a")), + value: Field("a"), + fields: map[string]float64{"b": 1}, + w: want{0, false}, + }, + { + name: "cv.Inner.Value not have fields", + Condition: ExistsCondition(Field("a")), + value: Field("b"), + fields: map[string]float64{"b": 1}, + w: want{0, false}, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + cv := &ConditionalValue{ + Condition: test.Condition, + Inner: test.value, + } + gotVal, gotBool := cv.Value(test.fields) + if gotVal != test.w.value { + t.Errorf("Value() gotVal = %v, want %v", gotVal, test.w.value) + } + if gotBool != test.w.exists { + t.Errorf("Value() gotBool = %v, want %v", gotBool, test.w.exists) + } + }) + } +} From 64e113194b1f835d5df0936bd3edd4af826db10a Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Tue, 10 Jan 2023 17:40:34 -0600 Subject: [PATCH 154/172] Fixed issue GO-2022-1144 (#296) - Fixed issue https://deps.dev/advisory/osv/GO-2022-1144 Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- go.mod | 6 +++--- go.sum | 6 ++++++ go.work.sum | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index fa605832..72a02543 100644 --- a/go.mod +++ b/go.mod @@ -73,11 +73,11 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect golang.org/x/crypto v0.1.0 // indirect - golang.org/x/net v0.2.0 // indirect + golang.org/x/net v0.4.0 // indirect golang.org/x/oauth2 v0.1.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/sys v0.2.0 // indirect - golang.org/x/text v0.4.0 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20221024183307-1bc688fe9f3e // indirect diff --git a/go.sum b/go.sum index 5a398dbf..6b3fb627 100644 --- a/go.sum +++ b/go.sum @@ -661,6 +661,8 @@ golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= +golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -769,6 +771,8 @@ golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -783,6 +787,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/go.work.sum b/go.work.sum index 4434a7f6..77d2fa54 100644 --- a/go.work.sum +++ b/go.work.sum @@ -366,6 +366,7 @@ golang.org/x/sync v0.0.0-20220929204114-8fcdb60fdcc0/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0 h1:z85xZCsEl7bi/KwbNADeBYoOP0++7W1ipu+aGnpwzRM= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/time v0.0.0-20220922220347-f3bd1da661af h1:Yx9k8YCG3dvF87UAn2tu2HQLf2dt/eR1bXxpLMWeH+Y= golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= From e1943613cde3b4aa7a7c3c8a1d7c821c4fd6f419 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Tue, 10 Jan 2023 17:51:34 -0600 Subject: [PATCH 155/172] Updated codeql to Include Golang (#295) - Updated codeql to include Golang Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- .github/workflows/codeql-analysis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 1f0fcc6f..cd869952 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python' ] + language: [ 'python', 'go' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed From 41ee75063a46a281a4fbb5826021cc7b3bce35a8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 13:41:03 +1100 Subject: [PATCH 156/172] Bump github.com/golangci/golangci-lint from 1.50.0 to 1.50.1 in /tools (#271) Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.50.0 to 1.50.1. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.50.0...v1.50.1) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tools/go.mod | 28 +++++++++++++++------------- tools/go.sum | 48 ++++++++++++++++++++++++++---------------------- 2 files changed, 41 insertions(+), 35 deletions(-) diff --git a/tools/go.mod b/tools/go.mod index b1ac9956..21b188b5 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -2,14 +2,17 @@ module github.com/ossf/criticality_score/tools go 1.19 -require github.com/golangci/golangci-lint v1.50.0 +require ( + github.com/golangci/golangci-lint v1.50.1 + mvdan.cc/gofumpt v0.4.0 +) require ( 4d63.com/gochecknoglobals v0.1.0 // indirect github.com/Abirdcfly/dupword v0.0.7 // indirect github.com/Antonboom/errname v0.1.7 // indirect github.com/Antonboom/nilnil v0.1.1 // indirect - github.com/BurntSushi/toml v1.2.0 // indirect + github.com/BurntSushi/toml v1.2.1 // indirect github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect github.com/GaijinEntertainment/go-exhaustruct/v2 v2.3.0 // indirect github.com/Masterminds/semver v1.5.0 // indirect @@ -29,7 +32,7 @@ require ( github.com/charithe/durationcheck v0.0.9 // indirect github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect - github.com/daixiang0/gci v0.8.0 // indirect + github.com/daixiang0/gci v0.8.1 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/esimonov/ifshort v1.0.4 // indirect @@ -71,14 +74,14 @@ require ( github.com/hashicorp/go-version v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/hexops/gotextdiff v1.0.3 // indirect - github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.1 // indirect github.com/jgautheron/goconst v1.5.1 // indirect github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/julz/importas v0.1.0 // indirect github.com/kisielk/errcheck v1.6.2 // indirect github.com/kisielk/gotool v1.0.0 // indirect - github.com/kkHAIKE/contextcheck v1.1.2 // indirect + github.com/kkHAIKE/contextcheck v1.1.3 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect github.com/kyoh86/exportloopref v0.1.8 // indirect @@ -133,7 +136,7 @@ require ( github.com/sourcegraph/go-diff v0.6.1 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.5.0 // indirect + github.com/spf13/cobra v1.6.0 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.13.0 // indirect @@ -146,8 +149,8 @@ require ( github.com/tetafro/godot v1.4.11 // indirect github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect github.com/timonwong/loggercheck v0.9.3 // indirect - github.com/tomarrell/wrapcheck/v2 v2.6.2 // indirect - github.com/tommy-muehle/go-mnd/v2 v2.5.0 // indirect + github.com/tomarrell/wrapcheck/v2 v2.7.0 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.0.3 // indirect github.com/ultraware/whitespace v0.0.5 // indirect github.com/uudashr/gocognit v1.0.6 // indirect @@ -159,17 +162,16 @@ require ( go.uber.org/zap v1.17.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect - golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect + golang.org/x/mod v0.6.0 // indirect golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect - golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/tools v0.1.12 // indirect + golang.org/x/sys v0.1.0 // indirect + golang.org/x/text v0.3.8 // indirect + golang.org/x/tools v0.2.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.3.3 // indirect - mvdan.cc/gofumpt v0.4.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect diff --git a/tools/go.sum b/tools/go.sum index 61b1e2d1..eabd0ced 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -45,8 +45,8 @@ github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0S github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= github.com/Antonboom/nilnil v0.1.1/go.mod h1:L1jBqoWM7AOeTD+tSquifKSesRHs4ZdaxvZR+xdJEaI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= -github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= +github.com/BurntSushi/toml v1.2.1 h1:9F2/+DoOYIOksmaJFPw1tGFy1eDnIJXg+UHjuD8lTak= +github.com/BurntSushi/toml v1.2.1/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= @@ -105,8 +105,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= -github.com/daixiang0/gci v0.8.0 h1:DzWYUm4+bc+taVUtuq1tsIMb/QFMMYgDIiykSoO98ZU= -github.com/daixiang0/gci v0.8.0/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/daixiang0/gci v0.8.1 h1:T4xpSC+hmsi4CSyuYfIJdMZAr9o7xZmHpQVygMghGZ4= +github.com/daixiang0/gci v0.8.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -207,8 +207,8 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.50.0 h1:+Xmyt8rKLauNLp2gzcxKMN8VNGqGc5Avc2ZLTwIOpEA= -github.com/golangci/golangci-lint v1.50.0/go.mod h1:UqtDvK24R9OizqRF06foPX8opRMzQB0HQK90uI2JgKc= +github.com/golangci/golangci-lint v1.50.1 h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY= +github.com/golangci/golangci-lint v1.50.1/go.mod h1:AQjHBopYS//oB8xs0y0M/dtxdKHkdhl0RvmjUct0/4w= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= @@ -285,8 +285,8 @@ github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUq github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= -github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc= +github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jgautheron/goconst v1.5.1 h1:HxVbL1MhydKs8R8n/HE5NPvzfaYmQJA3o879lE4+WcM= github.com/jgautheron/goconst v1.5.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= @@ -309,8 +309,8 @@ github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7 github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/kkHAIKE/contextcheck v1.1.2 h1:BYUSG/GhMhqVz//yjl8IkBDlMEws+9DtCmkz18QO1gg= -github.com/kkHAIKE/contextcheck v1.1.2/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo= +github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw= +github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -401,6 +401,7 @@ github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwb github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -483,8 +484,8 @@ github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.5.0 h1:X+jTBEBqF0bHN+9cSMgmfuvv2VHJ9ezmFNf9Y/XstYU= -github.com/spf13/cobra v1.5.0/go.mod h1:dWXEIy2H428czQCjInthrTRUg7yKbok+2Qi/yBIJoUM= +github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= +github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -522,10 +523,10 @@ github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDH github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw= -github.com/tomarrell/wrapcheck/v2 v2.6.2 h1:3dI6YNcrJTQ/CJQ6M/DUkc0gnqYSIk6o0rChn9E/D0M= -github.com/tomarrell/wrapcheck/v2 v2.6.2/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= -github.com/tommy-muehle/go-mnd/v2 v2.5.0 h1:iAj0a8e6+dXSL7Liq0aXPox36FiN1dBbjA6lt9fl65s= -github.com/tommy-muehle/go-mnd/v2 v2.5.0/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= +github.com/tomarrell/wrapcheck/v2 v2.7.0 h1:J/F8DbSKJC83bAvC6FoZaRjZiZ/iKoueSdrEkmGeacA= +github.com/tomarrell/wrapcheck/v2 v2.7.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= +github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= +github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= github.com/ultraware/funlen v0.0.3/go.mod h1:Dp4UiAus7Wdb9KUZsYWZEWiRzGuM2kXM1lPbfaF6xhA= github.com/ultraware/whitespace v0.0.5 h1:hh+/cpIcopyMYbZNVov9iSxvJU3OYQg78Sfaqzi/CzI= @@ -607,8 +608,9 @@ golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -645,8 +647,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b h1:PxfKdU9lEEDYjdIzOtC4qFWgkU2rGHdKlKowJSMN9h0= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -727,8 +729,8 @@ golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 h1:ohgcoMbSofXygzo6AD2I1kz3BFmW1QArPYTtwEM3UXc= -golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -738,8 +740,9 @@ golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -821,8 +824,9 @@ golang.org/x/tools v0.1.9-0.20211228192929-ee1ca4ffc4da/go.mod h1:nABZi5QlRsZVlz golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= -golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= From a6a5b57cf42f79015aedcd0957bb12b780790877 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 13:54:10 +1100 Subject: [PATCH 157/172] Bump actions/setup-go from 3.4.0 to 3.5.0 (#282) Bumps [actions/setup-go](https://github.com/actions/setup-go) from 3.4.0 to 3.5.0. - [Release notes](https://github.com/actions/setup-go/releases) - [Commits](https://github.com/actions/setup-go/compare/d0a58c1c4d2b25278816e339b944508c875f3613...6edd4406fa81c3da01a34fa6f6343087c207a568) --- updated-dependencies: - dependency-name: actions/setup-go dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 19d15751..3eb3f638 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -13,7 +13,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - - uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 with: go-version: 1.19 - name: Run tests @@ -24,7 +24,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 - - uses: actions/setup-go@d0a58c1c4d2b25278816e339b944508c875f3613 + - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 with: go-version: 1.19 - name: golangci-lint From 0ead4eebfbcd7bea4b28bedcebbbc5f006aa93e5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 13:59:14 +1100 Subject: [PATCH 158/172] Bump actions/checkout from 3.1.0 to 3.3.0 (#298) Bumps [actions/checkout](https://github.com/actions/checkout) from 3.1.0 to 3.3.0. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8...ac593985615ec2ede58e132d2e21d2b1cbd6127c) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/ci.yml | 4 ++-- .github/workflows/codeql-analysis.yml | 2 +- .github/workflows/scorecards.yml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3eb3f638..3d0a4f9e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -12,7 +12,7 @@ jobs: run-tests: runs-on: ubuntu-latest steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 with: go-version: 1.19 @@ -23,7 +23,7 @@ jobs: run-linter: runs-on: ubuntu-latest steps: - - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + - uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 with: go-version: 1.19 diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index cd869952..96f2c8f1 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -35,7 +35,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index c5f851e4..badc9ad3 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -19,7 +19,7 @@ jobs: id-token: write steps: - name: "Checkout code" - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c - name: "Run analysis" uses: ossf/scorecard-action@e38b1902ae4f44df626f11ba0734b14fb91f8f86 # v2.0.0-alpha.2 with: From b148d93395c5cc004fcb2237a9b008b45d8c4937 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 11 Jan 2023 15:04:28 +1100 Subject: [PATCH 159/172] Bump actions/upload-artifact from 3.1.1 to 3.1.2 (#303) Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3.1.1 to 3.1.2. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/83fd05a356d7e2593de66fc9913b3002723633cb...0b7f8abb1508181956e8e162db84b466c27e18ce) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/scorecards.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index badc9ad3..bed5b18e 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -34,7 +34,7 @@ jobs: # https://docs.github.com/en/actions/advanced-guides/storing-workflow-data-as-artifacts # Optional. - name: "Upload artifact" - uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v2 + uses: actions/upload-artifact@0b7f8abb1508181956e8e162db84b466c27e18ce # v2 with: name: SARIF file path: results.sarif From 9e753863b41d1939e9d47cd575e088fd625fa9fb Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Mon, 16 Jan 2023 17:04:29 -0600 Subject: [PATCH 160/172] Updated docs for scorer input (#284) - Updated the docs for scorer input. - https://github.com/ossf/criticality_score/issues/281 Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- cmd/scorer/README.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/cmd/scorer/README.md b/cmd/scorer/README.md index fbb61536..8123baa1 100644 --- a/cmd/scorer/README.md +++ b/cmd/scorer/README.md @@ -141,4 +141,31 @@ Use STDIN and STDOUT on a subset of data for fast iteration. For example: $ head -10 raw_signals.csv | go run ./cmd/scorer \ -config config/scorer/original_pike.yml \ - -``` \ No newline at end of file +``` + +Here is an example of raw signals for `scorer` input: + +```csv +repo.url,repo.language,repo.license,repo.star_count,repo.created_at,repo.updated_at,legacy.created_since,legacy.updated_since,legacy.contributor_count,legacy.org_count,legacy.commit_frequency,legacy.recent_release_count,legacy.updated_issues_count,legacy.closed_issues_count,legacy.issue_comment_frequency,legacy.github_mention_count,depsdev.dependent_count,default_score,collection_date +https://github.com/ashawkey/RAD-NeRF,Python,MIT License,64,2022-11-23T02:51:07Z,2022-11-23T04:32:02Z,0,0,1,1,0.1,0,0,0,0,0,,0.13958,2022-11-28T02:47:06Z +https://github.com/0DeFi/Solana-NFT-Minting,Python,,19,2022-11-23T17:55:35Z,2022-11-23T18:00:21Z,0,0,1,1,0.06,0,0,0,0,0,,0.13907,2022-11-28T02:47:06Z +https://github.com/0DeFi/Cardano-NFT-Minting,Python,MIT License,19,2022-11-23T17:52:59Z,2022-11-23T18:02:20Z,0,0,1,1,0.1,0,0,0,0,0,,0.13958,2022-11-28T02:47:06Z +https://github.com/0DeFi/MagicEden-Minting-Bot,Python,MIT License,19,2022-11-23T17:58:09Z,2022-11-23T17:59:23Z,0,0,1,1,0.06,0,0,0,0,0,,0.13907,2022-11-28T02:47:06Z +https://github.com/trungdq88/Awesome-Black-Friday-Cyber-Monday,,,1414,2022-11-22T06:16:23Z,2022-11-26T17:42:31Z,0,0,274,7,17.19,0,356,344,0.19,2,,0.43088,2022-11-28T02:47:06Z +https://github.com/HuolalaTech/hll-wp-glog,PHP,Apache License 2.0,99,2022-11-22T02:37:31Z,2022-11-22T17:22:42Z,0,0,1,0,0.06,1,2,0,0,0,,0.12770,2022-11-28T02:47:06Z +https://github.com/flo-at/rustsnake,Rust,MIT License,76,2022-11-14T23:28:32Z,2022-11-25T23:33:43Z,0,0,2,1,0.44,0,2,2,2,0,,0.20238,2022-11-28T02:47:06Z +https://github.com/SeeFlowerX/estrace,Go,MIT License,68,2022-11-22T09:26:34Z,2022-11-24T03:50:27Z,0,0,1,0,0.1,2,1,1,1,0,,0.15949,2022-11-28T02:47:06Z +https://github.com/proofxyz/solidify,Go,MIT License,74,2022-11-22T16:16:23Z,2022-11-22T16:40:06Z,0,0,1,1,0.04,1,4,1,1,0,,0.18551,2022-11-28T02:47:06Z +https://github.com/caidukai/sms-interception,Swift,MIT License,54,2022-11-22T04:47:22Z,2022-11-22T10:03:20Z,0,0,1,0,0.21,0,1,1,0,0,,0.12112,2022-11-28T02:47:06Z +https://github.com/WeilunWang/SinDiffusion,Python,Apache License 2.0,88,2022-11-22T03:52:52Z,2022-11-24T09:03:19Z,0,0,1,1,0.33,0,2,1,0,0,,0.15222,2022-11-28T02:47:06Z +https://github.com/adobe-research/convmelspec,Python,Apache License 2.0,72,2022-11-22T17:29:53Z,2022-11-22T17:56:50Z,0,0,2,1,0.08,1,0,0,0,0,,0.15841,2022-11-28T02:47:06Z +https://github.com/avuenja/tabnews-app,Dart,MIT License,54,2022-11-22T00:13:25Z,2022-11-27T19:03:14Z,0,0,2,2,1.02,5,33,25,0.97,0,,0.26024,2022-11-28T02:47:06Z +https://github.com/Sheng-T/FedMGD,Python,Other,33,2022-11-22T01:51:32Z,2022-11-22T12:52:14Z,0,0,2,0,0.27,0,0,0,0,0,,0.12310,2022-11-28T02:47:06Z +https://github.com/bmarsh9/gapps,HTML,Other,27,2022-11-22T00:04:32Z,2022-11-23T23:32:21Z,0,0,2,0,0.23,0,10,0,0.4,1,,0.15769,2022-11-28T02:47:06Z +https://github.com/ankane/polars-ruby,Ruby,MIT License,57,2022-11-22T05:59:43Z,2022-11-28T02:09:26Z,0,0,1,0,4.44,292,1,0,0,0,,0.18558,2022-11-28T02:47:06Z +https://github.com/adnanali-in/cfi_b22_classwork,JavaScript,,23,2022-11-22T04:51:23Z,2022-11-25T04:32:01Z,0,0,1,1,0.1,0,0,0,0,0,,0.13958,2022-11-28T02:47:06Z +https://github.com/georgetomzaridis/aade-publicity-search-js,JavaScript,MIT License,23,2022-11-22T01:29:45Z,2022-11-23T13:35:27Z,0,0,2,2,0.33,0,3,3,0.33,1,,0.20273,2022-11-28T02:47:06Z +https://github.com/mobcode1337/Twitter-Account-Creator,Python,,19,2022-11-22T12:58:49Z,2022-11-23T00:10:02Z,0,0,1,0,0.04,0,0,0,0,0,,0.11128,2022-11-28T02:47:06Z +``` + +An example for the raw signal data can be found at: https://commondatastorage.googleapis.com/ossf-criticality-score/index.html?prefix=2022.11.28/024706/ \ No newline at end of file From fd48817b33fd2e8df2bc32cf289bc7229aac4deb Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Mon, 23 Jan 2023 10:12:30 +1100 Subject: [PATCH 161/172] Add Milestone 2 documentation. (#175) * Add draft Milestone 2 doc so WG members can see it early. * Update m2 docs Signed-off-by: Caleb Brown * Further updates to the Milestone 2 doc. Signed-off-by: Caleb Brown * More m2 doc updates. More links. Signed-off-by: Caleb Brown * typo fix Signed-off-by: Caleb Brown Signed-off-by: Caleb Brown --- .../images/github-enumeration-infra.svg | 1 + docs/design/milestone_2.md | 262 ++++++++++++++++++ 2 files changed, 263 insertions(+) create mode 100644 docs/design/images/github-enumeration-infra.svg create mode 100644 docs/design/milestone_2.md diff --git a/docs/design/images/github-enumeration-infra.svg b/docs/design/images/github-enumeration-infra.svg new file mode 100644 index 00000000..05fe760c --- /dev/null +++ b/docs/design/images/github-enumeration-infra.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/design/milestone_2.md b/docs/design/milestone_2.md new file mode 100644 index 00000000..00312be5 --- /dev/null +++ b/docs/design/milestone_2.md @@ -0,0 +1,262 @@ +# Criticality Score Revamp: Milestone 2 - Productionizing + +- Author: [Caleb Brown](mailto:calebbrown@google.com) +- Updated: 2022-11-18 + +## Goals + +The primary goal of Milestone 2 is to ensure the fresh criticality score data is +always available and enable continuous improvement on how the scores are +calculated. + +To achieve this the criticality score system will be productionized to +continuously update the criticality score for GitHub repositories with at least +20 stars. + +### Non-Goals + +The same non-goals for +[Milestone 1](https://github.com/ossf/criticality_score/blob/main/docs/design/milestone_1.md) +apply to this milestone: + +- Improving the score +- Covering source repositories on non-GitHub hosts +- De-duping mirrors + +While these are important, they are beyond the scope of this milestone. + +## Background + +This work is a follow up to +[Milestone 1](https://github.com/ossf/criticality_score/blob/main/docs/design/milestone_1.md). + +The Criticality Score project is used by the OpenSSF and the Securing Critical +Projects Work Group (WG) for determining which Open Source projects are +"critical". Critical Open Source projects are those which are broadly depended +on by organizations, and present a security risk to those organizations, and +their customers, if they are not supported. + +Improving the criticality score requires introducing new data sources and +signals and collecting them across all repositories. + +Additionally the open source ecosystem is dynamic, and an unassuming project can +quickly become critical if it becomes a dependency of one or two popular +projects. + +### Key Challenges + +There are two key challenges with collecting and scoring critical projects: + +1. Duration +2. API token management + +Duration makes it impractical for an individual to run the signal data +themselves across a large number of open source projects. An interruption or +failure across multiple days or weeks needed to complete the signal collection +requires constant monitoring. + +Efficiently collecting signals requires access to many GitHub API tokens and +monitoring of quotas to avoid unnecessary delays when quotas are met. Multiple +tokens also allows greater parallelism and faster collection. + +Building centralized infrastructure for automating the collection of signals +across all open source projects helps address these challenges. + +### Scorecard Infrastructure + +The Scorecard project has already built out automation for collecting and +aggregating data across hundreds of thousands of repositories, as documented in +[Scalable Scorecard](https://github.com/ossf/scorecard/blob/main/docs/design/scalable_scorecards.md). + +Productionizing the collection of signals for calculating a criticality score +aligns well with this infrastructure. + +## Design + +### Enumeration + +[![GitHub Enumeration Infra Design](images/github-enumeration-infra.svg)](https://github.com/ossf/criticality_score/blob/main/cmd/enumerate_github/) + +#### Initiation + +A Kubernetes schedule starts the enumeration process ([ref](https://github.com/ossf/criticality_score/blob/main/infra/k8s/enumerate_github.yaml)). + +Initially the enumeration will be scheduled to be run weekly. + +#### Output + +##### Project URLs + +After completion, the enumerated project URLs will be stored in one or more text +files in a bucket with a prefix containing a unique `runID`. + +`runID` will be the start date and time (UTC) in `YYYYMMDD-HHmm` format. E.g. +`20220810-1302` or `20220810-2359`. + +The filename(s) for the urls will be unique to the enumerator used. They must be +a key that identifies the enumerator, and have an extension of `.txt`. + +For GitHub enumeration the key will be `github`, so the filename will be +`github.txt`. + +Full example: `bucket/20220810-1302/github.txt` + +##### Marker file + +After all text files are written to the `runID` based prefix, a marker file will +be written with the prefix for the last completed run. Subsequent runs will +overwrite the same marker file. + +While it is possible to identify the most recent `runID` by iterating through +entries in a bucket, a marker file avoids the issues of iterating through items +in a bucket (e.g. race conditions). + +#### Implementation + +The GitHub enumeration tool will be altered in the following way: + +- Support environment variables along with flags for easy configuration through + kubeconfig YAML files. +- The ability to specify a destination bucket and file for project URLs. `runID` + can be specified using a token (e.g. `[[run-id]]`). +- The ability to specify a destination bucket and file for the marker file. + +Cloud infrastructure changes: + +- A service worker needs to be associated with the enumeration. +- A bucket with write access by the above service worker. + - A lifecycle policy on the bucket to clean up stale data. +- A Kubernetes configuration with the following: + - The desired schedule + - The destination bucket and path structure + - The address + port of the Scorecard GitHub token auth server + +#### Out of Scope for Enumeration + +##### Additional Reliability and Performance + +GitHub enumeration is reasonably reliable already, however it is still +susceptible to failures (e.g. network, cloud storage). + +Given that the GitHub enumeration only takes 4-6 hours to complete for all +projects with at least 10 stars, additional efforts to improve reliability will +be deferred. + +In the future an architecture similar to the Signal Collection and Scorecard +project can be used to improve performance and reliability. + +##### Deduplication + +Deduplication of URLs from different sources is out of scope. Long term this +will be important to ensure API quotas are used efficiently. For Milestone 2, +deduplication will be done when results are being reduced as this needs to be +handled anyway (e.g. a timeout triggers a second set of signals to be collected +for the same repository). + +### Signal Collection + +To scale signal collection we will build upon the Scorecard project's +infrastructure. + +The +[Scalable Scorecard](https://github.com/ossf/scorecard/blob/main/docs/design/scalable_scorecards.md) +covers the specifics of the Scorecard infrastructure. + +To use the Scorecard infrastructure we will need to make the following changes +to the Scorecard project: + +- Controller URL iteration ([ref](https://github.com/ossf/scorecard/blob/main/cron/internal/data/iterator.go)) + - Identify the prefix to search from the marker file. + - Read from `bucket/{runID}/*.csv` instead of the static CSV file. +- Worker library ([ref](https://github.com/ossf/scorecard/blob/main/cron/internal/worker/main.go)) + - Create a reusable library for: + - consuming PubSub messages containing work shards + - writing the shards to storage +- Data-transfer library ([ref](https://github.com/ossf/scorecard/blob/main/cron/internal/bq/main.go)) + - A reusable library for determining if all shards are present, and: iterating + over the files (e.g. BigQuery loader) and/or iterating over each record in + the resulting CSV files. + +Additionally, the following changes need to be made to the Criticality Score +project: + +- Implement a criticality score specific worker ([ref](https://github.com/ossf/criticality_score/blob/main/cmd/collect_signals/)) + - Refactor and clone the `collect_signals` tool into a new `criticality_score` + command, which continues as a CLI focused tool for end-users. + - Adapt the `collect_signals` command to: + - use the "worker library" above to consume shards of work from a PubSub + channel. + - write each shard as a JSON file to a primary bucket location for BigQuery + import. + - write each shard also as a CSV file to a secondary bucket location for + aggregation into a large CSV file. + - consume configuration information from the scorecard config.yaml file, + and environment variables. + - apply a default score during collection. +- Implement a criticality score specific data-transfer service to combine CSV + data together ([ref](https://github.com/ossf/criticality_score/blob/main/cmd/csv_transfer/)). + +Cloud Infrastructure Changes: + +- Signal collection will run in a separate cluster to Scorecard + - It will use an independent set of GitHub auth tokens and a separate server + to avoid starving Scorecard. +- Cron timing will differ. +- Additional CSV transfer service will need to be created. + +### Monitoring + +- Token Usage: clone scorecard dashboard and update OpenCensus prefix. +- Health: + - Clone scorecard dashboard and update OpenCensus prefix. + - HTTP request response codes (also by "source"). + - Errors rates by "Source". + - Worker restarts. + +### Release Process + +How to deploy updates. + +- Setup: + - Built around [Google Cloud Deploy](https://cloud.google.com/deploy) and + [Google Cloud Build](https://cloud.google.com/build). + - All Kubernetes configs are stored in a general form, with Kustomize used + to alter the config to match the deployment environment. + - `config.yaml` is versioned by Kustomize and tied to the commit ID. + - Any scorecard docker images will be pinned to the same scorecard commit ID + as set in `go.mod` to ensure consistency. +- **Build** + - Trigger: A PR is merge to *main* + - Process: + 1. Build Docker images, tagged with commit ID. +- **Staging** + - Trigger: Once every weekday, if there is a new build. + - Process: + 1. Ensure that the images for the latest commit ID on *main* exist (this is + to ensure a *build* is not in progress). + 1. Create a new release in Google Cloud Deploy, which triggers a deploy to + the staging environment. +- **Production** + - Trigger: Manually, from a successful staging build. + - Process: + 1. From the Google Cloud Deploy interface "promote" a successful staging + release to production. + +## Rollout Plan + +Phase 1: proving/testing integration + +- Create a new GKE cluster. +- Setup Cloud Build to automatically create images for each new commit. +- Setup k8s configs using latest images and run the pods in the new cluster. + - Enumeration will run in the Scorecard cluster as its token usage is limited + and well understood. +- Tweak the configurations until the integration is working well. + +Phase 2: staging -> production + +- Move to a staging + production configuration as documented in Release Process. + - On commit - staging will be updated to the latest images. + - Staging will use a limited set of data (O(1000) repos) to allow for regular + runs. + - Promotion from staging to production will be a manual step. From 238bc64512352b9d8981f1d713e74bb2475e9acc Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Thu, 26 Jan 2023 13:42:34 -0600 Subject: [PATCH 162/172] Included tests for internal/log/env (#309) * Included tests for internal/log/env - Included tests for internal/log/env - Included licenses for `env.go` and `config.go` Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Fixed based on code review Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- internal/log/config.go | 14 +++++ internal/log/env.go | 14 +++++ internal/log/env_test.go | 111 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 internal/log/env_test.go diff --git a/internal/log/config.go b/internal/log/config.go index cfa33c8d..0af92c24 100644 --- a/internal/log/config.go +++ b/internal/log/config.go @@ -1,3 +1,17 @@ +// Copyright 2023 Criticality Score 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 +// +// 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. + package log import ( diff --git a/internal/log/env.go b/internal/log/env.go index 32a4e922..8d8b86e0 100644 --- a/internal/log/env.go +++ b/internal/log/env.go @@ -1,3 +1,17 @@ +// Copyright 2023 Criticality Score 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 +// +// 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. + package log import "errors" diff --git a/internal/log/env_test.go b/internal/log/env_test.go new file mode 100644 index 00000000..5c6cc80d --- /dev/null +++ b/internal/log/env_test.go @@ -0,0 +1,111 @@ +// Copyright 2023 Criticality Score 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 +// +// 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. + +package log + +import ( + "bytes" + "math" + "testing" +) + +func TestLookupEnv(t *testing.T) { + tests := []struct { + name string + text string + want Env + }{ + {"dev", "dev", DevEnv}, + {"gcp", "gcp", GCPEnv}, + {"unknown", "unknown", UnknownEnv}, + {"empty", "", UnknownEnv}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := LookupEnv(test.text); got != test.want { + t.Errorf("LookupEnv() = %v, want %v", got, test.want) + } + }) + } +} + +func TestEnv_String(t *testing.T) { + tests := []struct { //nolint:govet + name string + e Env + want string + }{ + {"dev", DevEnv, "dev"}, + {"gcp", GCPEnv, "gcp"}, + {"unknown", UnknownEnv, "unknown"}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if got := test.e.String(); got != test.want { + t.Errorf("String() = %v, want %v", got, test.want) + } + }) + } +} + +func TestEnv_UnmarshalText(t *testing.T) { + tests := []struct { //nolint:govet + name string + e Env + text []byte + value string + wantErr bool + }{ + { + name: "unknown", + text: []byte("unknown"), + value: "unknown", + wantErr: true, + }, + { + name: "dev", + text: []byte("dev"), + value: "dev", + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + if err := test.e.UnmarshalText(test.text); (err != nil) != test.wantErr || test.e.String() != test.value { + t.Errorf("UnmarshalText() error = %v, wantErr %v", err, test.wantErr) + } + }) + } +} + +func TestEnv_MarshalText(t *testing.T) { + tests := []struct { //nolint:govet + name string + e Env + want []byte + }{ + {"dev", DevEnv, []byte("dev")}, + {"unknown", UnknownEnv, []byte("unknown")}, + {"empty", math.MaxInt, []byte("unknown")}, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + got, err := test.e.MarshalText() + + if !bytes.Equal(got, test.want) || err != nil { + // this function never returns an error so err should always be nil + t.Errorf("MarshalText() got = %v, want %v", got, test.want) + } + }) + } +} From a3d961d08d8658c0415643937f6aa146ac1932d9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 27 Jan 2023 09:36:37 +1100 Subject: [PATCH 163/172] Bump golangci/golangci-lint-action from 3.3.0 to 3.4.0 (#313) Bumps [golangci/golangci-lint-action](https://github.com/golangci/golangci-lint-action) from 3.3.0 to 3.4.0. - [Release notes](https://github.com/golangci/golangci-lint-action/releases) - [Commits](https://github.com/golangci/golangci-lint-action/compare/07db5389c99593f11ad7b44463c2d4233066a9b1...08e2f20817b15149a52b5b3ebe7de50aff2ba8c5) --- updated-dependencies: - dependency-name: golangci/golangci-lint-action dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Caleb Brown --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3d0a4f9e..29a5348d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -28,4 +28,4 @@ jobs: with: go-version: 1.19 - name: golangci-lint - uses: golangci/golangci-lint-action@07db5389c99593f11ad7b44463c2d4233066a9b1 + uses: golangci/golangci-lint-action@08e2f20817b15149a52b5b3ebe7de50aff2ba8c5 From eaecabdd9fd5123ff3f06f5cb5e9bc31698ebda4 Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Sun, 29 Jan 2023 23:07:10 -0600 Subject: [PATCH 164/172] Updated tests for internal/signalio/type (#307) * Updated tests for internal/signalio/type - Changed the package name for the tests from signalio_test to signalio - Updated test Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated based on code review Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> --------- Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- internal/signalio/type_test.go | 66 ++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/internal/signalio/type_test.go b/internal/signalio/type_test.go index 8497ee4a..0f5c1fe1 100644 --- a/internal/signalio/type_test.go +++ b/internal/signalio/type_test.go @@ -15,9 +15,13 @@ package signalio_test import ( + "bytes" "errors" + "math" + "reflect" "testing" + "github.com/ossf/criticality_score/internal/collector/signal" "github.com/ossf/criticality_score/internal/signalio" ) @@ -52,6 +56,7 @@ func TestTypeMarshalText(t *testing.T) { }{ {name: "csv", writerType: signalio.WriterTypeCSV, want: "csv"}, {name: "json", writerType: signalio.WriterTypeJSON, want: "json"}, + {name: "text", writerType: signalio.WriterTypeText, want: "text"}, {name: "unknown", writerType: signalio.WriterType(10), want: "", err: signalio.ErrorUnknownWriterType}, } for _, test := range tests { @@ -81,6 +86,7 @@ func TestTypeUnmarshalText(t *testing.T) { }{ {input: "csv", want: signalio.WriterTypeCSV}, {input: "json", want: signalio.WriterTypeJSON}, + {input: "text", want: signalio.WriterTypeText}, {input: "", want: 0, err: signalio.ErrorUnknownWriterType}, {input: "unknown", want: 0, err: signalio.ErrorUnknownWriterType}, } @@ -102,3 +108,63 @@ func TestTypeUnmarshalText(t *testing.T) { }) } } + +func TestWriterType_New(t *testing.T) { + type args struct { + emptySets []signal.Set + extra []string + } + tests := []struct { //nolint:govet + name string + t signalio.WriterType + args args + want any + }{ + { + name: "csv", + t: signalio.WriterTypeCSV, + args: args{ + emptySets: []signal.Set{}, + extra: []string{}, + }, + want: signalio.CSVWriter(&bytes.Buffer{}, []signal.Set{}, ""), + }, + { + name: "json", + t: signalio.WriterTypeJSON, + args: args{ + emptySets: []signal.Set{}, + extra: []string{}, + }, + want: signalio.JSONWriter(&bytes.Buffer{}), + }, + { + name: "text", + t: signalio.WriterTypeText, + args: args{ + emptySets: []signal.Set{}, + extra: []string{}, + }, + want: signalio.TextWriter(&bytes.Buffer{}, []signal.Set{}, ""), + }, + { + name: "unknown", + t: signalio.WriterType(math.MaxInt), + args: args{ + emptySets: []signal.Set{}, + extra: []string{}, + }, + want: nil, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + w := &bytes.Buffer{} + got := test.t.New(w, test.args.emptySets, test.args.extra...) + + if reflect.TypeOf(got) != reflect.TypeOf(test.want) { + t.Fatalf("New() == %v, want %v", reflect.TypeOf(got), reflect.TypeOf(test.want)) + } + }) + } +} From b00d69e57e7afcdc17730bb500d32761a50cd94c Mon Sep 17 00:00:00 2001 From: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Date: Tue, 31 Jan 2023 16:14:16 -0600 Subject: [PATCH 165/172] Removed GlobalRegistry from registry.go (#316) * Removed GlobalRegistry from registry.go Removed the `GlobalRegisty` variable from `internal/scorer/algorithm/registry.go` because it isn't good practice to use global variables. I was able to remove `GlobalRegistry` because the only places any function in `registry.go` was being used was in `wam.go` and `config.go`. The `Register()` function (`registry.go`) was only being used in the `init()` funcion (`wam.go`). The `NewALgorithm()` function (`registry.go`) was only being used in the `Algorithm()` function (`config.go`). Since those were the only places any function from `registry.go` was being used externaly I created a `NewRegistry()` in `Algorithm()` and then registered it, and returned `r.NewAlgorithm()`. Because of creating a `NewRegistry()` and registering it in `Algorithm` I removed the `init()` function in `wam.go` because it wasn't being used. I also removed the `Register()` and `NewAlgorithm()` functions from `registry.go` because they weren't being used. I also removed `GlobalRegisty`. Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated based on code review Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> --------- Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> --- internal/scorer/algorithm/registry.go | 13 ------------- internal/scorer/algorithm/wam/wam.go | 8 +++----- internal/scorer/config.go | 6 +++++- 3 files changed, 8 insertions(+), 19 deletions(-) diff --git a/internal/scorer/algorithm/registry.go b/internal/scorer/algorithm/registry.go index 4b819eb2..6e4047c0 100644 --- a/internal/scorer/algorithm/registry.go +++ b/internal/scorer/algorithm/registry.go @@ -16,9 +16,6 @@ package algorithm import "fmt" -// GlobalRegistry is the global, application wide, registry for all algorithms. -var GlobalRegistry = NewRegistry() - // Registry is used to map a name to a Factory that creates Algorithm instances // for the given name. type Registry struct { @@ -55,13 +52,3 @@ func (r *Registry) NewAlgorithm(name string, inputs []*Input) (Algorithm, error) } return f(inputs) } - -// Register calls Register on the GlobalRegistry. -func Register(name string, f Factory) { - GlobalRegistry.Register(name, f) -} - -// NewAlgorithm calls NewAlgorithm on the GlobalRegsitry. -func NewAlgorithm(name string, inputs []*Input) (Algorithm, error) { - return GlobalRegistry.NewAlgorithm(name, inputs) -} diff --git a/internal/scorer/algorithm/wam/wam.go b/internal/scorer/algorithm/wam/wam.go index 2149e064..cc7e8f3b 100644 --- a/internal/scorer/algorithm/wam/wam.go +++ b/internal/scorer/algorithm/wam/wam.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// The package wam implements the Weighted Arithmetic Mean, which forms the +// Package wam implements the Weighted Arithmetic Mean, which forms the // basis of Rob Pike's criticality score algorithm as documented in // Quantifying_criticality_algorithm.pdf. package wam @@ -21,6 +21,8 @@ import ( "github.com/ossf/criticality_score/internal/scorer/algorithm" ) +const Name = "weighted_arithmetic_mean" + type WeighetedArithmeticMean struct { inputs []*algorithm.Input } @@ -46,7 +48,3 @@ func (p *WeighetedArithmeticMean) Score(record map[string]float64) float64 { } return s / totalWeight } - -func init() { - algorithm.Register("weighted_arithmetic_mean", New) -} diff --git a/internal/scorer/config.go b/internal/scorer/config.go index 33505e79..94ac3e7a 100644 --- a/internal/scorer/config.go +++ b/internal/scorer/config.go @@ -22,6 +22,7 @@ import ( "gopkg.in/yaml.v3" "github.com/ossf/criticality_score/internal/scorer/algorithm" + "github.com/ossf/criticality_score/internal/scorer/algorithm/wam" ) type Condition struct { @@ -137,6 +138,7 @@ func LoadConfig(r io.Reader) (*Config, error) { // nil will be returned if the algorithm cannot be returned. func (c *Config) Algorithm() (algorithm.Algorithm, error) { var inputs []*algorithm.Input + r := algorithm.NewRegistry() for _, i := range c.Inputs { input, err := i.ToAlgorithmInput() if err != nil { @@ -144,5 +146,7 @@ func (c *Config) Algorithm() (algorithm.Algorithm, error) { } inputs = append(inputs, input) } - return algorithm.NewAlgorithm(c.Name, inputs) + + r.Register(wam.Name, wam.New) + return r.NewAlgorithm(c.Name, inputs) } From 66a39f043df23bce5c2816f7e2457a2213a129e8 Mon Sep 17 00:00:00 2001 From: Brandon Simmons Date: Thu, 2 Feb 2023 19:07:04 -0500 Subject: [PATCH 166/172] Provide working installation instructions (#320) #288 Signed-off-by: Brandon Simmons --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3b6f3e64..32bdb4d0 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ open source project: The program only requires one argument to run, the name of the repo: ```shell -$ go install github.com/ossf/criticality_score/cmd/criticality_score +$ go install github.com/ossf/criticality_score/cmd/criticality_score@main $ criticality_score github.com/kubernetes/kubernetes repo.name: kubernetes From 9c806d449c323c6ace2927140e4f2bd2ad9f29ff Mon Sep 17 00:00:00 2001 From: Nathan Naveen <42319948+nathannaveen@users.noreply.github.com> Date: Wed, 8 Feb 2023 04:18:33 -0600 Subject: [PATCH 167/172] Refactored Score in wam.go (#315) - Refacted `Score()` in `wam.go` to make it cleaner Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- internal/scorer/algorithm/wam/wam.go | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/internal/scorer/algorithm/wam/wam.go b/internal/scorer/algorithm/wam/wam.go index cc7e8f3b..0843d7a9 100644 --- a/internal/scorer/algorithm/wam/wam.go +++ b/internal/scorer/algorithm/wam/wam.go @@ -39,12 +39,10 @@ func (p *WeighetedArithmeticMean) Score(record map[string]float64) float64 { var totalWeight float64 var s float64 for _, i := range p.inputs { - v, ok := i.Value(record) - if !ok { - continue + if v, ok := i.Value(record); ok { + totalWeight += i.Weight + s += i.Weight * v } - totalWeight += i.Weight - s += i.Weight * v } return s / totalWeight } From fd5feb10c24a98aa8dade5ca0c17e7ad1d533d25 Mon Sep 17 00:00:00 2001 From: Nathan Naveen <42319948+nathannaveen@users.noreply.github.com> Date: Wed, 8 Feb 2023 04:29:27 -0600 Subject: [PATCH 168/172] Refactored internal/collector/depsdev/source (#324) - `DefaultDatasetName` wasn't used, so I removed it. - I also replaced all of the `return err` with `return fmt.Errorf()` because it's considered good practice in Go to use fmt.Errorf() instead of just returning "err" as it provides more informative error messages. The fmt.Errorf() function formats a string into an error, allowing for added context and information that can aid in debugging and troubleshooting. On the other hand, returning just "err" without any extra information can make it harder to comprehend the error's cause and solution. Furthermore, using a formatted error message enhances error handling and debugging consistency. Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> Co-authored-by: Caleb Brown --- internal/collector/depsdev/source.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/internal/collector/depsdev/source.go b/internal/collector/depsdev/source.go index 4b33d7e2..23c4c70d 100644 --- a/internal/collector/depsdev/source.go +++ b/internal/collector/depsdev/source.go @@ -16,6 +16,7 @@ package depsdev import ( "context" + "fmt" "net/url" "strings" "time" @@ -28,8 +29,7 @@ import ( ) const ( - defaultLocation = "US" - DefaultDatasetName = "depsdev_analysis" + defaultLocation = "US" ) type depsDevSet struct { @@ -37,7 +37,7 @@ type depsDevSet struct { } func (s *depsDevSet) Namespace() signal.Namespace { - return signal.Namespace("depsdev") + return "depsdev" } type depsDevSource struct { @@ -63,7 +63,7 @@ func (c *depsDevSource) Get(ctx context.Context, r projectrepo.Repo, jobID strin c.logger.With(zap.String("url", r.URL().String())).Debug("Fetching deps.dev dependent count") deps, found, err := c.dependents.Count(ctx, n, t, jobID) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to fetch deps.dev dependent count: %w", err) } if found { s.DependentCount.Set(deps) @@ -82,14 +82,14 @@ func NewSource(ctx context.Context, logger *zap.Logger, projectID, datasetName s } gcpClient, err := bigquery.NewClient(ctx, projectID) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create bigquery client: %w", err) } // Set the location gcpClient.Location = defaultLocation dependents, err := NewDependents(ctx, gcpClient, logger, datasetName, datasetTTL) if err != nil { - return nil, err + return nil, fmt.Errorf("failed to create deps.dev dependents: %w", err) } return &depsDevSource{ From 1a6ce7c97c7ed24ba42fcb2c5370082ee2972843 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 9 Feb 2023 10:41:15 +1100 Subject: [PATCH 169/172] Bump github.com/golangci/golangci-lint from 1.50.1 to 1.51.1 in /tools (#323) Bumps [github.com/golangci/golangci-lint](https://github.com/golangci/golangci-lint) from 1.50.1 to 1.51.1. - [Release notes](https://github.com/golangci/golangci-lint/releases) - [Changelog](https://github.com/golangci/golangci-lint/blob/master/CHANGELOG.md) - [Commits](https://github.com/golangci/golangci-lint/compare/v1.50.1...v1.51.1) --- updated-dependencies: - dependency-name: github.com/golangci/golangci-lint dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- tools/go.mod | 81 +++++++++++----------- tools/go.sum | 189 +++++++++++++++++++++++++++------------------------ 2 files changed, 144 insertions(+), 126 deletions(-) diff --git a/tools/go.mod b/tools/go.mod index 21b188b5..99afb2e1 100644 --- a/tools/go.mod +++ b/tools/go.mod @@ -3,13 +3,14 @@ module github.com/ossf/criticality_score/tools go 1.19 require ( - github.com/golangci/golangci-lint v1.50.1 + github.com/golangci/golangci-lint v1.51.1 mvdan.cc/gofumpt v0.4.0 ) require ( - 4d63.com/gochecknoglobals v0.1.0 // indirect - github.com/Abirdcfly/dupword v0.0.7 // indirect + 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect + 4d63.com/gochecknoglobals v0.2.1 // indirect + github.com/Abirdcfly/dupword v0.0.9 // indirect github.com/Antonboom/errname v0.1.7 // indirect github.com/Antonboom/nilnil v0.1.1 // indirect github.com/BurntSushi/toml v1.2.1 // indirect @@ -30,27 +31,27 @@ require ( github.com/butuzov/ireturn v0.1.1 // indirect github.com/cespare/xxhash/v2 v2.1.2 // indirect github.com/charithe/durationcheck v0.0.9 // indirect - github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 // indirect + github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 // indirect github.com/curioswitch/go-reassign v0.2.0 // indirect - github.com/daixiang0/gci v0.8.1 // indirect + github.com/daixiang0/gci v0.9.0 // indirect github.com/davecgh/go-spew v1.1.1 // indirect github.com/denis-tingaikin/go-header v0.4.3 // indirect github.com/esimonov/ifshort v1.0.4 // indirect github.com/ettle/strcase v0.1.1 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.14.1 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/firefart/nonamedreturns v1.0.4 // indirect github.com/fsnotify/fsnotify v1.5.4 // indirect github.com/fzipp/gocyclo v0.6.0 // indirect github.com/go-critic/go-critic v0.6.5 // indirect github.com/go-toolsmith/astcast v1.0.0 // indirect - github.com/go-toolsmith/astcopy v1.0.2 // indirect + github.com/go-toolsmith/astcopy v1.0.3 // indirect github.com/go-toolsmith/astequal v1.0.3 // indirect github.com/go-toolsmith/astfmt v1.0.0 // indirect github.com/go-toolsmith/astp v1.0.0 // indirect github.com/go-toolsmith/strparse v1.0.0 // indirect github.com/go-toolsmith/typep v1.0.2 // indirect - github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b // indirect + github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect github.com/gobwas/glob v0.2.3 // indirect github.com/gofrs/flock v0.8.1 // indirect github.com/golang/protobuf v1.5.2 // indirect @@ -60,11 +61,11 @@ require ( github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 // indirect github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 // indirect github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca // indirect - github.com/golangci/misspell v0.3.5 // indirect + github.com/golangci/misspell v0.4.0 // indirect github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 // indirect github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 // indirect github.com/google/go-cmp v0.5.9 // indirect - github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 // indirect + github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 // indirect github.com/gostaticanalysis/analysisutil v0.7.1 // indirect github.com/gostaticanalysis/comment v1.4.2 // indirect github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect @@ -79,40 +80,41 @@ require ( github.com/jingyugao/rowserrcheck v1.1.1 // indirect github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect github.com/julz/importas v0.1.0 // indirect - github.com/kisielk/errcheck v1.6.2 // indirect + github.com/junk1tm/musttag v0.4.4 // indirect + github.com/kisielk/errcheck v1.6.3 // indirect github.com/kisielk/gotool v1.0.0 // indirect github.com/kkHAIKE/contextcheck v1.1.3 // indirect github.com/kulti/thelper v0.6.3 // indirect github.com/kunwardeep/paralleltest v1.0.6 // indirect - github.com/kyoh86/exportloopref v0.1.8 // indirect + github.com/kyoh86/exportloopref v0.1.11 // indirect github.com/ldez/gomoddirectives v0.2.3 // indirect - github.com/ldez/tagliatelle v0.3.1 // indirect - github.com/leonklingele/grouper v1.1.0 // indirect + github.com/ldez/tagliatelle v0.4.0 // indirect + github.com/leonklingele/grouper v1.1.1 // indirect github.com/lufeee/execinquery v1.2.1 // indirect github.com/magiconair/properties v1.8.6 // indirect github.com/maratori/testableexamples v1.0.0 // indirect github.com/maratori/testpackage v1.1.0 // indirect github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/mattn/go-isatty v0.0.17 // indirect github.com/mattn/go-runewidth v0.0.9 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect github.com/mbilski/exhaustivestruct v1.2.0 // indirect - github.com/mgechev/revive v1.2.4 // indirect + github.com/mgechev/revive v1.2.5 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moricho/tparallel v0.2.1 // indirect github.com/nakabonne/nestif v0.3.1 // indirect github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 // indirect - github.com/nishanths/exhaustive v0.8.3 // indirect + github.com/nishanths/exhaustive v0.9.5 // indirect github.com/nishanths/predeclared v0.2.2 // indirect + github.com/nunnatsa/ginkgolinter v0.8.1 // indirect github.com/olekukonko/tablewriter v0.0.5 // indirect github.com/pelletier/go-toml v1.9.5 // indirect github.com/pelletier/go-toml/v2 v2.0.5 // indirect - github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/polyfloyd/go-errorlint v1.0.5 // indirect + github.com/polyfloyd/go-errorlint v1.0.6 // indirect github.com/prometheus/client_golang v1.12.1 // indirect github.com/prometheus/client_model v0.2.0 // indirect github.com/prometheus/common v0.32.1 // indirect @@ -121,35 +123,36 @@ require ( github.com/quasilyte/gogrep v0.0.0-20220828223005-86e4605de09f // indirect github.com/quasilyte/regex/syntax v0.0.0-20200407221936-30656e2c4a95 // indirect github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect - github.com/ryancurrah/gomodguard v1.2.4 // indirect - github.com/ryanrolds/sqlclosecheck v0.3.0 // indirect - github.com/sanposhiho/wastedassign/v2 v2.0.6 // indirect + github.com/ryancurrah/gomodguard v1.3.0 // indirect + github.com/ryanrolds/sqlclosecheck v0.4.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect github.com/sashamelentyev/interfacebloat v1.1.0 // indirect - github.com/sashamelentyev/usestdlibvars v1.20.0 // indirect - github.com/securego/gosec/v2 v2.13.1 // indirect + github.com/sashamelentyev/usestdlibvars v1.21.1 // indirect + github.com/securego/gosec/v2 v2.14.0 // indirect github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/sivchari/containedctx v1.0.2 // indirect github.com/sivchari/nosnakecase v1.7.0 // indirect - github.com/sivchari/tenv v1.7.0 // indirect + github.com/sivchari/tenv v1.7.1 // indirect github.com/sonatard/noctx v0.0.1 // indirect - github.com/sourcegraph/go-diff v0.6.1 // indirect + github.com/sourcegraph/go-diff v0.7.0 // indirect github.com/spf13/afero v1.8.2 // indirect github.com/spf13/cast v1.5.0 // indirect - github.com/spf13/cobra v1.6.0 // indirect + github.com/spf13/cobra v1.6.1 // indirect github.com/spf13/jwalterweatherman v1.1.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/viper v1.13.0 // indirect github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect - github.com/stretchr/objx v0.4.0 // indirect - github.com/stretchr/testify v1.8.0 // indirect + github.com/stretchr/objx v0.5.0 // indirect + github.com/stretchr/testify v1.8.1 // indirect github.com/subosito/gotenv v1.4.1 // indirect + github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect github.com/tdakkota/asciicheck v0.1.1 // indirect github.com/tetafro/godot v1.4.11 // indirect - github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 // indirect + github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e // indirect github.com/timonwong/loggercheck v0.9.3 // indirect - github.com/tomarrell/wrapcheck/v2 v2.7.0 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.0 // indirect github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ultraware/funlen v0.0.3 // indirect github.com/ultraware/whitespace v0.0.5 // indirect @@ -161,18 +164,18 @@ require ( go.uber.org/multierr v1.6.0 // indirect go.uber.org/zap v1.17.0 // indirect golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect - golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 // indirect - golang.org/x/mod v0.6.0 // indirect - golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde // indirect - golang.org/x/sys v0.1.0 // indirect - golang.org/x/text v0.3.8 // indirect - golang.org/x/tools v0.2.0 // indirect + golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a // indirect + golang.org/x/mod v0.7.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.4.0 // indirect + golang.org/x/text v0.6.0 // indirect + golang.org/x/tools v0.5.0 // indirect google.golang.org/protobuf v1.28.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - honnef.co/go/tools v0.3.3 // indirect + honnef.co/go/tools v0.4.0 // indirect mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed // indirect mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b // indirect - mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 // indirect + mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d // indirect ) diff --git a/tools/go.sum b/tools/go.sum index eabd0ced..37b9b921 100644 --- a/tools/go.sum +++ b/tools/go.sum @@ -1,5 +1,7 @@ -4d63.com/gochecknoglobals v0.1.0 h1:zeZSRqj5yCg28tCkIV/z/lWbwvNm5qnKVS15PI8nhD0= -4d63.com/gochecknoglobals v0.1.0/go.mod h1:wfdC5ZjKSPr7CybKEcgJhUOgeAQW1+7WcyK8OvUilfo= +4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= +4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= +4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= @@ -38,8 +40,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/Abirdcfly/dupword v0.0.7 h1:z14n0yytA3wNO2gpCD/jVtp/acEXPGmYu0esewpBt6Q= -github.com/Abirdcfly/dupword v0.0.7/go.mod h1:K/4M1kj+Zh39d2aotRwypvasonOyAMH1c/IZJzE0dmk= +github.com/Abirdcfly/dupword v0.0.9 h1:MxprGjKq3yDBICXDgEEsyGirIXfMYXkLNT/agPsE1tk= +github.com/Abirdcfly/dupword v0.0.9/go.mod h1:PzmHVLLZ27MvHSzV7eFmMXSFArWXZPZmfuuziuUrf2g= github.com/Antonboom/errname v0.1.7 h1:mBBDKvEYwPl4WFFNwec1CZO096G6vzK9vvDQzAwkako= github.com/Antonboom/errname v0.1.7/go.mod h1:g0ONh16msHIPgJSGsecu1G/dcF2hlYR/0SddnIAGavU= github.com/Antonboom/nilnil v0.1.1 h1:PHhrh5ANKFWRBh7TdYmyyq2gyT2lotnvFvvFbylF81Q= @@ -91,8 +93,8 @@ github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cb github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/charithe/durationcheck v0.0.9 h1:mPP4ucLrf/rKZiIG/a9IPXHGlh8p4CzgpyTy6EEutYk= github.com/charithe/durationcheck v0.0.9/go.mod h1:SSbRIBVfMjCi/kEB6K65XEA83D6prSM8ap1UCpNKtgg= -github.com/chavacava/garif v0.0.0-20220630083739-93517212f375 h1:E7LT642ysztPWE0dfz43cWOvMiF42DyTRC+eZIaO4yI= -github.com/chavacava/garif v0.0.0-20220630083739-93517212f375/go.mod h1:4m1Rv7xfuwWPNKXlThldNuJvutYM6J95wNuuVmn55To= +github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 h1:cy5GCEZLUCshCGCRRUjxHrDUqkB4l5cuUt3ShEckQEo= +github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348/go.mod h1:f/miWtG3SSuTxKsNK3o58H1xl+XV6ZIfbC6p7lPPB8U= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -105,8 +107,8 @@ github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ3 github.com/cristalhq/acmd v0.8.1/go.mod h1:LG5oa43pE/BbxtfMoImHCQN++0Su7dzipdgBjMCBVDQ= github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= -github.com/daixiang0/gci v0.8.1 h1:T4xpSC+hmsi4CSyuYfIJdMZAr9o7xZmHpQVygMghGZ4= -github.com/daixiang0/gci v0.8.1/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= +github.com/daixiang0/gci v0.9.0 h1:t8XZ0vK6l0pwPoOmoGyqW2NwQlvbpAQNVvu/GRBgykM= +github.com/daixiang0/gci v0.9.0/go.mod h1:EpVfrztufwVgQRXjnX4zuNinEpLj5OmMjtu/+MB0V0c= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -122,8 +124,8 @@ github.com/esimonov/ifshort v1.0.4 h1:6SID4yGWfRae/M7hkVDVVyppy8q/v9OuxNdmjLQStB github.com/esimonov/ifshort v1.0.4/go.mod h1:Pe8zjlRrJ80+q2CxHLfEOfTwxCZ4O+MuhcHcfgNWTk0= github.com/ettle/strcase v0.1.1 h1:htFueZyVeE1XNnMEfbqp5r67qAN/4r6ya1ysq8Q+Zcw= github.com/ettle/strcase v0.1.1/go.mod h1:hzDLsPC7/lwKyBOywSHEP89nt2pDgdy+No1NBA9o9VY= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= -github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.14.1 h1:qfhVLaG5s+nCROl1zJsZRxFeYrHLqWroPOQ8BWiNb4w= +github.com/fatih/color v1.14.1/go.mod h1:2oHN61fhTpgcxD3TSWCgKDiH1+x4OiDVVGH8WlgGZGg= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= github.com/firefart/nonamedreturns v1.0.4 h1:abzI1p7mAEPYuR4A+VLKn4eNDOycjYo2phmY9sfv40Y= @@ -144,12 +146,12 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g= github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4= -github.com/go-toolsmith/astcopy v1.0.2 h1:YnWf5Rnh1hUudj11kei53kI57quN/VH6Hp1n+erozn0= github.com/go-toolsmith/astcopy v1.0.2/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= +github.com/go-toolsmith/astcopy v1.0.3 h1:r0bgSRlMOAgO+BdQnVAcpMSMkrQCnV6ZJmIkrJgcJj0= +github.com/go-toolsmith/astcopy v1.0.3/go.mod h1:4TcEdbElGc9twQEYpVo/aieIXfHhiuLh4aLAck6dO7Y= github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY= github.com/go-toolsmith/astequal v1.0.2/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= github.com/go-toolsmith/astequal v1.0.3 h1:+LVdyRatFS+XO78SGV4I3TCEA0AC7fKEGma+fH+674o= @@ -164,8 +166,8 @@ github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUD github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk= github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b h1:khEcpUM4yFcxg4/FHQWkvVRmgijNXRfzkIDHh23ggEo= -github.com/go-xmlfmt/xmlfmt v0.0.0-20191208150333-d5b6f63a941b/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= +github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= @@ -207,14 +209,14 @@ github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe h1:6RGUuS7EGotKx6 github.com/golangci/go-misc v0.0.0-20220329215616-d24fe342adfe/go.mod h1:gjqyPShc/m8pEMpk0a3SeagVb0kaqvhscv+i9jI5ZhQ= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2 h1:amWTbTGqOZ71ruzrdA+Nx5WA3tV1N0goTspwmKCQvBY= github.com/golangci/gofmt v0.0.0-20220901101216-f2edd75033f2/go.mod h1:9wOXstvyDRshQ9LggQuzBCGysxs3b6Uo/1MvYCR2NMs= -github.com/golangci/golangci-lint v1.50.1 h1:C829clMcZXEORakZlwpk7M4iDw2XiwxxKaG504SZ9zY= -github.com/golangci/golangci-lint v1.50.1/go.mod h1:AQjHBopYS//oB8xs0y0M/dtxdKHkdhl0RvmjUct0/4w= +github.com/golangci/golangci-lint v1.51.1 h1:N5HD/x0ZrhJYsgKWyz7yJxxQ8JKR0Acc+FOP7QtGSAA= +github.com/golangci/golangci-lint v1.51.1/go.mod h1:hnyNNO3fJ2Rjwo6HM+VXvcmLkKDOuBAnR9gVlS1mW1E= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0 h1:MfyDlzVjl1hoaPzPD4Gpb/QgoRfSBR0jdhwGyAWwMSA= github.com/golangci/lint-1 v0.0.0-20191013205115-297bf364a8e0/go.mod h1:66R6K6P6VWk9I95jvqGxkqJxVWGFy9XlDwLwVz1RCFg= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca h1:kNY3/svz5T29MYHubXix4aDDuE3RWHkPvopM/EDv/MA= github.com/golangci/maligned v0.0.0-20180506175553-b1d89398deca/go.mod h1:tvlJhZqDe4LMs4ZHD0oMUlt9G2LWuDGoisJTBzLMV9o= -github.com/golangci/misspell v0.3.5 h1:pLzmVdl3VxTOncgzHcvLOKirdvcx/TydsClUQXTehjo= -github.com/golangci/misspell v0.3.5/go.mod h1:dEbvlSfYbMQDtrpRMQU675gSDLDNa8sCPPChZ7PhiVA= +github.com/golangci/misspell v0.4.0 h1:KtVB/hTK4bbL/S6bs64rYyk8adjmh1BygbBiaAiX+a0= +github.com/golangci/misspell v0.4.0/go.mod h1:W6O/bwV6lGDxUCChm2ykw9NQdd5bYd1Xkjo88UcWyJc= github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6 h1:DIPQnGy2Gv2FSA4B/hh8Q7xx3B7AIDk3DAMeHclH1vQ= github.com/golangci/revgrep v0.0.0-20220804021717-745bb2f7c2e6/go.mod h1:0AKcRCkMoKvUvlf89F6O7H2LYdhr1zBh736mBItOdRs= github.com/golangci/unconvert v0.0.0-20180507085042-28b1c447d1f4 h1:zwtduBRr5SSWhqsYNgcuWO2kFlpdOZbP0+yRjmvPGys= @@ -253,9 +255,8 @@ github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8 h1:PVRE9d4AQKmbelZ7emNig1+NT27DUmKZn5qXxfio54U= -github.com/gordonklaus/ineffassign v0.0.0-20210914165742-4cc7213b9bc8/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= -github.com/gostaticanalysis/analysisutil v0.0.0-20190318220348-4088753ea4d3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= +github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28 h1:9alfqbrhuD+9fLZ4iaAVwhlp5PEhmnBt7yvK2Oy5C1U= +github.com/gordonklaus/ineffassign v0.0.0-20230107090616-13ace0543b28/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= github.com/gostaticanalysis/analysisutil v0.0.3/go.mod h1:eEOZF4jCKGi+aprrirO9e7WKB3beBRtWgqGunKl6pKE= github.com/gostaticanalysis/analysisutil v0.1.0/go.mod h1:dMhHRU9KTiDcuLGdy87/2gTR8WruwYZrKdRq9m1O6uw= github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= @@ -293,7 +294,6 @@ github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjz github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= -github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -305,8 +305,10 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= -github.com/kisielk/errcheck v1.6.2 h1:uGQ9xI8/pgc9iOoCe7kWQgRE6SBTrCGmTSf0LrEtY7c= -github.com/kisielk/errcheck v1.6.2/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= +github.com/junk1tm/musttag v0.4.4 h1:VK4L7v7lvWAhKDDx0cUJgbb0UBNipYinv8pPeHJzH9Q= +github.com/junk1tm/musttag v0.4.4/go.mod h1:XkcL/9O6RmD88JBXb+I15nYRl9W4ExhgQeCBEhfMC8U= +github.com/kisielk/errcheck v1.6.3 h1:dEKh+GLHcWm2oN34nMvDzn1sqI0i0WxPvrgiJA5JuM8= +github.com/kisielk/errcheck v1.6.3/go.mod h1:nXw/i/MfnvRHqXa7XXmQMUB0oNFGuBrNI8d8NLy0LPw= github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw= @@ -325,15 +327,14 @@ github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= github.com/kunwardeep/paralleltest v1.0.6 h1:FCKYMF1OF2+RveWlABsdnmsvJrei5aoyZoaGS+Ugg8g= github.com/kunwardeep/paralleltest v1.0.6/go.mod h1:Y0Y0XISdZM5IKm3TREQMZ6iteqn1YuwCsJO/0kL9Zes= -github.com/kyoh86/exportloopref v0.1.8 h1:5Ry/at+eFdkX9Vsdw3qU4YkvGtzuVfzT4X7S77LoN/M= -github.com/kyoh86/exportloopref v0.1.8/go.mod h1:1tUcJeiioIs7VWe5gcOObrux3lb66+sBqGZrRkMwPgg= +github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= +github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= github.com/ldez/gomoddirectives v0.2.3 h1:y7MBaisZVDYmKvt9/l1mjNCiSA1BVn34U0ObUcJwlhA= github.com/ldez/gomoddirectives v0.2.3/go.mod h1:cpgBogWITnCfRq2qGoDkKMEVSaarhdBr6g8G04uz6d0= -github.com/ldez/tagliatelle v0.3.1 h1:3BqVVlReVUZwafJUwQ+oxbx2BEX2vUG4Yu/NOfMiKiM= -github.com/ldez/tagliatelle v0.3.1/go.mod h1:8s6WJQwEYHbKZDsp/LjArytKOG8qaMrKQQ3mFukHs88= -github.com/leonklingele/grouper v1.1.0 h1:tC2y/ygPbMFSBOs3DcyaEMKnnwH7eYKzohOtRrf0SAg= -github.com/leonklingele/grouper v1.1.0/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= -github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/ldez/tagliatelle v0.4.0 h1:sylp7d9kh6AdXN2DpVGHBRb5guTVAgOxqNGhbqc4b1c= +github.com/ldez/tagliatelle v0.4.0/go.mod h1:mNtTfrHy2haaBAw+VT7IBV6VXBThS7TCreYWbBcJ87I= +github.com/leonklingele/grouper v1.1.1 h1:suWXRU57D4/Enn6pXR0QVqqWWrnJ9Osrz+5rjt8ivzU= +github.com/leonklingele/grouper v1.1.1/go.mod h1:uk3I3uDfi9B6PeUjsCKi6ndcf63Uy7snXgR4yDYQVDY= github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= @@ -346,22 +347,19 @@ github.com/matoous/godox v0.0.0-20210227103229-6504466cf951 h1:pWxk9e//NbPwfxat7 github.com/matoous/godox v0.0.0-20210227103229-6504466cf951/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= -github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= -github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17 h1:BTarxUcIeDqL27Mc+vyvdWYSL28zpIhv3RoTdsLMPng= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= -github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mbilski/exhaustivestruct v1.2.0 h1:wCBmUnSYufAHO6J4AVWY6ff+oxWxsVFrwgOdMUQePUo= github.com/mbilski/exhaustivestruct v1.2.0/go.mod h1:OeTBVxQWoEmB2J2JCHmXWPJ0aksxSUOUy+nvtVEfzXc= -github.com/mgechev/revive v1.2.4 h1:+2Hd/S8oO2H0Ikq2+egtNwQsVhAeELHjxjIUFX5ajLI= -github.com/mgechev/revive v1.2.4/go.mod h1:iAWlQishqCuj4yhV24FTnKSXGpbAA+0SckXB8GQMX/Q= +github.com/mgechev/revive v1.2.5 h1:UF9AR8pOAuwNmhXj2odp4mxv9Nx2qUIwVz8ZsU+Mbec= +github.com/mgechev/revive v1.2.5/go.mod h1:nFOXent79jMTISAfOAasKfy0Z2Ejq0WX7Qn/KAdYopI= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= @@ -381,14 +379,16 @@ github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354 h1:4kuARK6Y6Fx github.com/nbutton23/zxcvbn-go v0.0.0-20210217022336-fa2cb2858354/go.mod h1:KSVJerMDfblTH7p5MZaTt+8zaT2iEk3AkVb9PQdZuE8= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= -github.com/nishanths/exhaustive v0.8.3 h1:pw5O09vwg8ZaditDp/nQRqVnrMczSJDxRDJMowvhsrM= -github.com/nishanths/exhaustive v0.8.3/go.mod h1:qj+zJJUgJ76tR92+25+03oYUhzF4R7/2Wk7fGTfCHmg= +github.com/nishanths/exhaustive v0.9.5 h1:TzssWan6orBiLYVqewCG8faud9qlFntJE30ACpzmGME= +github.com/nishanths/exhaustive v0.9.5/go.mod h1:IbwrGdVMizvDcIxPYGVdQn5BqWJaOwpCvg4RGb8r/TA= github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nunnatsa/ginkgolinter v0.8.1 h1:/y4o/0hV+ruUHj4xXh89xlFjoaitnI4LnkpuYs02q1c= +github.com/nunnatsa/ginkgolinter v0.8.1/go.mod h1:FYYLtszIdmzCH8XMaMPyxPVXZ7VCaIm55bA+gugx+14= github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= -github.com/onsi/ginkgo/v2 v2.1.4 h1:GNapqRSid3zijZ9H77KrgVG4/8KqiyRsxcSxe+7ApXY= -github.com/onsi/gomega v1.20.0 h1:8W0cWlwFkflGPLltQvLRB7ZVD5HuP6ng320w2IS245Q= +github.com/onsi/ginkgo/v2 v2.3.1 h1:8SbseP7qM32WcvE6VaN6vfXxv698izmsJ1UQX9ve7T8= +github.com/onsi/gomega v1.22.1 h1:pY8O4lBfsHKZHM/6nrxkhVPUznOlIu3quZcKP/M20KI= github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= @@ -399,8 +399,6 @@ github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3v github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/pelletier/go-toml/v2 v2.0.5 h1:ipoSadvV8oGUjnUbMub59IDPPwfxF694nG/jwbMiyQg= github.com/pelletier/go-toml/v2 v2.0.5/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d h1:CdDQnGF8Nq9ocOS/xlSptM1N3BbrA6/kmaep5ggwaIA= -github.com/phayes/checkstyle v0.0.0-20170904204023-bfd46e6a821d/go.mod h1:3OzsM7FXDQlpCiw2j81fOmAwQLnZnLGXVKUzeKQXIAw= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -409,8 +407,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/polyfloyd/go-errorlint v1.0.5 h1:AHB5JRCjlmelh9RrLxT9sgzpalIwwq4hqE8EkwIwKdY= -github.com/polyfloyd/go-errorlint v1.0.5/go.mod h1:APVvOesVSAnne5SClsPxPdfvZTVDojXh1/G3qb5wjGI= +github.com/polyfloyd/go-errorlint v1.0.6 h1:ZevdyEGxDoHAMQUVvdTT06hnYuKULe8TQkOmIYx6s1c= +github.com/polyfloyd/go-errorlint v1.0.6/go.mod h1:NcnNncnm8fVV7vfQWiI4HZrzWFzGp24C262IQutNcMs= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= @@ -449,18 +447,18 @@ github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/ryancurrah/gomodguard v1.2.4 h1:CpMSDKan0LtNGGhPrvupAoLeObRFjND8/tU1rEOtBp4= -github.com/ryancurrah/gomodguard v1.2.4/go.mod h1:+Kem4VjWwvFpUJRJSwa16s1tBJe+vbv02+naTow2f6M= -github.com/ryanrolds/sqlclosecheck v0.3.0 h1:AZx+Bixh8zdUBxUA1NxbxVAS78vTPq4rCb8OUZI9xFw= -github.com/ryanrolds/sqlclosecheck v0.3.0/go.mod h1:1gREqxyTGR3lVtpngyFo3hZAgk0KCtEdgEkHwDbigdA= -github.com/sanposhiho/wastedassign/v2 v2.0.6 h1:+6/hQIHKNJAUixEj6EmOngGIisyeI+T3335lYTyxRoA= -github.com/sanposhiho/wastedassign/v2 v2.0.6/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/ryancurrah/gomodguard v1.3.0 h1:q15RT/pd6UggBXVBuLps8BXRvl5GPBcwVA7BJHMLuTw= +github.com/ryancurrah/gomodguard v1.3.0/go.mod h1:ggBxb3luypPEzqVtq33ee7YSN35V28XeGnid8dnni50= +github.com/ryanrolds/sqlclosecheck v0.4.0 h1:i8SX60Rppc1wRuyQjMciLqIzV3xnoHB7/tXbr6RGYNI= +github.com/ryanrolds/sqlclosecheck v0.4.0/go.mod h1:TBRRjzL31JONc9i4XMinicuo+s+E8yKZ5FN8X3G6CKQ= +github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= +github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= -github.com/sashamelentyev/usestdlibvars v1.20.0 h1:K6CXjqqtSYSsuyRDDC7Sjn6vTMLiSJa4ZmDkiokoqtw= -github.com/sashamelentyev/usestdlibvars v1.20.0/go.mod h1:0GaP+ecfZMXShS0A94CJn6aEuPRILv8h/VuWI9n1ygg= -github.com/securego/gosec/v2 v2.13.1 h1:7mU32qn2dyC81MH9L2kefnQyRMUarfDER3iQyMHcjYM= -github.com/securego/gosec/v2 v2.13.1/go.mod h1:EO1sImBMBWFjOTFzMWfTRrZW6M15gm60ljzrmy/wtHo= +github.com/sashamelentyev/usestdlibvars v1.21.1 h1:GQGlReyL9Ek8DdJmwtwhHbhwHnuPfsKaprpjnrPcjxc= +github.com/sashamelentyev/usestdlibvars v1.21.1/go.mod h1:MPI52Qq99iO9sFZZcKJ2y/bx6BNjs+/2bw3PCggIbew= +github.com/securego/gosec/v2 v2.14.0 h1:U1hfs0oBackChXA72plCYVA4cOlQ4gO+209dHiSNZbI= +github.com/securego/gosec/v2 v2.14.0/go.mod h1:Ff03zEi5NwSOfXj9nFpBfhbWTtROCkg9N+9goggrYn4= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= @@ -474,18 +472,18 @@ github.com/sivchari/containedctx v1.0.2 h1:0hLQKpgC53OVF1VT7CeoFHk9YKstur1XOgfYI github.com/sivchari/containedctx v1.0.2/go.mod h1:PwZOeqm4/DLoJOqMSIJs3aKqXRX4YO+uXww087KZ7Bw= github.com/sivchari/nosnakecase v1.7.0 h1:7QkpWIRMe8x25gckkFd2A5Pi6Ymo0qgr4JrhGt95do8= github.com/sivchari/nosnakecase v1.7.0/go.mod h1:CwDzrzPea40/GB6uynrNLiorAlgFRvRbFSgJx2Gs+QY= -github.com/sivchari/tenv v1.7.0 h1:d4laZMBK6jpe5PWepxlV9S+LC0yXqvYHiq8E6ceoVVE= -github.com/sivchari/tenv v1.7.0/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= +github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= github.com/sonatard/noctx v0.0.1 h1:VC1Qhl6Oxx9vvWo3UDgrGXYCeKCe3Wbw7qAWL6FrmTY= github.com/sonatard/noctx v0.0.1/go.mod h1:9D2D/EoULe8Yy2joDHJj7bv3sZoq9AaSb8B4lqBjiZI= -github.com/sourcegraph/go-diff v0.6.1 h1:hmA1LzxW0n1c3Q4YbrFgg4P99GSnebYa3x8gr0HZqLQ= -github.com/sourcegraph/go-diff v0.6.1/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= +github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= github.com/spf13/afero v1.8.2 h1:xehSyVa0YnHWsJ49JFljMpg1HX19V6NDZ1fkm1Xznbo= github.com/spf13/afero v1.8.2/go.mod h1:CtAatgMJh6bJEIs48Ay/FOnkljP3WeGUG0MC1RfAqwo= github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w= github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU= -github.com/spf13/cobra v1.6.0 h1:42a0n6jwCot1pUmomAp4T7DeMD+20LFv4Q54pxLf2LI= -github.com/spf13/cobra v1.6.0/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= +github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA= +github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY= github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= @@ -498,8 +496,9 @@ github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.1.4/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= @@ -507,10 +506,13 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= github.com/tdakkota/asciicheck v0.1.1 h1:PKzG7JUTUmVspQTDqtkX9eSiLGossXTybutHwTXuO0A= github.com/tdakkota/asciicheck v0.1.1/go.mod h1:yHp0ai0Z9gUljN3o0xMhYJnH/IcvkdTBOX2fmJ93JEM= github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= @@ -519,12 +521,12 @@ github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpR github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= github.com/tetafro/godot v1.4.11 h1:BVoBIqAf/2QdbFmSwAWnaIqDivZdOV0ZRwEm6jivLKw= github.com/tetafro/godot v1.4.11/go.mod h1:LR3CJpxDVGlYOWn3ZZg1PgNZdTUvzsZWu8xaEohUpn8= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144 h1:kl4KhGNsJIbDHS9/4U9yQo1UcPQM0kOMJHn29EoH/Ro= -github.com/timakin/bodyclose v0.0.0-20210704033933-f49887972144/go.mod h1:Qimiffbc6q9tBWlVV6x0P9sat/ao1xEkREYPPj9hphk= +github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e h1:MV6KaVu/hzByHP0UvJ4HcMGE/8a6A4Rggc/0wx2AvJo= +github.com/timakin/bodyclose v0.0.0-20221125081123-e39cf3fc478e/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= github.com/timonwong/loggercheck v0.9.3 h1:ecACo9fNiHxX4/Bc02rW2+kaJIAMAes7qJ7JKxt0EZI= github.com/timonwong/loggercheck v0.9.3/go.mod h1:wUqnk9yAOIKtGA39l1KLE9Iz0QiTocu/YZoOf+OzFdw= -github.com/tomarrell/wrapcheck/v2 v2.7.0 h1:J/F8DbSKJC83bAvC6FoZaRjZiZ/iKoueSdrEkmGeacA= -github.com/tomarrell/wrapcheck/v2 v2.7.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= +github.com/tomarrell/wrapcheck/v2 v2.8.0 h1:qDzbir0xmoE+aNxGCPrn+rUSxAX+nG6vREgbbXAR81I= +github.com/tomarrell/wrapcheck/v2 v2.8.0/go.mod h1:ao7l5p0aOlUNJKI0qVwB4Yjlqutd0IvAB9Rdwyilxvg= github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/ultraware/funlen v0.0.3 h1:5ylVWm8wsNwH5aWo9438pwvsK0QiqVuUrt9bn7S/iLA= @@ -567,6 +569,7 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -580,8 +583,9 @@ golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMk golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA= golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e/go.mod h1:Kr81I6Kryrl9sr8s2FK3vxD90NdsKWRuOIl2O4CvYbA= golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= -golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91 h1:Ic/qN6TEifvObMGQy72k0n1LlJr7DjWWEi+MOsDOiSk= golang.org/x/exp/typeparams v0.0.0-20220827204233-334a2380cb91/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a h1:Jw5wfR+h9mnIYH+OtGT2im5wV1YGGDora5vTv/aa5bE= +golang.org/x/exp/typeparams v0.0.0-20221208152030-732eee02a75a/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -609,8 +613,9 @@ golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.6.0 h1:b9gGHsz9/HhJ3HF5DHQytPpuwocVTChQJK3AvoLRD5I= golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -648,7 +653,11 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.1.0 h1:hZ/3BUoy5aId7sCpA/Tc5lt8DkFgdVS2onTpJsZ/fl0= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= +golang.org/x/net v0.5.0 h1:GyT4nK/YDHSqa1c4753ouYCDajOYKTja9Xb/OHtgvSw= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -671,8 +680,8 @@ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde h1:ejfdSekXMDxDLbRrJMwUk6KnSLZ2McaUCVcIKM+N6jc= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -690,7 +699,6 @@ golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -719,7 +727,6 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -729,10 +736,17 @@ golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.1.0 h1:kunALQeHf1/185U1i0GOB/fy1IPRDDpuoOOqRReG57U= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0 h1:Zr2JFtRQNX3BCZ8YtxRE9hNJYC8J6I1MVbMg6owUp18= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -741,8 +755,10 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0 h1:3XmdazWV+ubf7QgHSTWeykHOci5oeekaGJBLkrkaw4k= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -756,7 +772,6 @@ golang.org/x/tools v0.0.0-20190311215038-5c2858a9cfe5/go.mod h1:LCzVGOaR6xXOjkQ3 golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190322203728-c1a832b0ad89/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= @@ -795,9 +810,7 @@ golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roY golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200622203043-20e05c1c8ffa/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200624225443-88f3c62a19ff/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200625211823-6506e20df31f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= @@ -807,7 +820,6 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20200831203904-5a2aa26beb65/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20200904185747-39188db58858/go.mod h1:Cj7w3i3Rnn0Xh82ur9kSqwfTHTeVxaDqrfMjpcNT6bE= golang.org/x/tools v0.0.0-20201001104356-43ebab892c4c/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= -golang.org/x/tools v0.0.0-20201002184944-ecd9fd270d5d/go.mod h1:z6u4i615ZeAfBE4XtMziQW1fSVJXACjjbWkB/mvPzlU= golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201110124207-079ba7bd75cd/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20201201161351-ac6f37ff4c2a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= @@ -825,8 +837,11 @@ golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.2.0 h1:G6AHpWxTMGY1KyEYoAQ5WTtIekUUvDNjan3ugu60JvE= golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= +golang.org/x/tools v0.5.0 h1:+bSpV5HIeWkuvgaMfI3UmKRThoTA5ODJTUd8T17NO+4= +golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -951,16 +966,16 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA= -honnef.co/go/tools v0.3.3/go.mod h1:jzwdWgg7Jdq75wlfblQxO4neNaFFSvgc1tD5Wv8U0Yw= +honnef.co/go/tools v0.4.0 h1:lyXVV1c8wUBJRKqI8JgIpT8TW1VDagfYYaxbKa/HoL8= +honnef.co/go/tools v0.4.0/go.mod h1:36ZgoUOrqOk1GxwHhyryEkq8FQWkUO2xGuSMhUCcdvA= mvdan.cc/gofumpt v0.4.0 h1:JVf4NN1mIpHogBj7ABpgOyZc65/UUOkKQFkoURsz4MM= mvdan.cc/gofumpt v0.4.0/go.mod h1:PljLOHDeZqgS8opHRKLzp2It2VBuSdteAgqUfzMTxlQ= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed h1:WX1yoOaKQfddO/mLzdV4wptyWgoH/6hwLs7QHTixo0I= mvdan.cc/interfacer v0.0.0-20180901003855-c20040233aed/go.mod h1:Xkxe497xwlCKkIaQYRfC7CSLworTXY9RMqwhhCm+8Nc= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b h1:DxJ5nJdkhDlLok9K6qO+5290kphDJbHOQO1DFFFTeBo= mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jCoyKnw3vv5biOc3JnIcYfL4= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442 h1:seuXWbRB1qPrS3NQnHmFKLJLtskWyueeIzmLXghMGgk= -mvdan.cc/unparam v0.0.0-20220706161116-678bad134442/go.mod h1:F/Cxw/6mVrNKqrR2YjFf5CaW0Bw4RL8RfbEf4GRggJk= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d h1:3rvTIIM22r9pvXk+q3swxUQAQOxksVMGK7sml4nG57w= +mvdan.cc/unparam v0.0.0-20221223090309-7455f1af531d/go.mod h1:IeHQjmn6TOD+e4Z3RFiZMMsLVL+A96Nvptar8Fj71is= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= From 730ffd907dd1b768bb84b6faa4d5fda1ac1d9798 Mon Sep 17 00:00:00 2001 From: Nathan Naveen <42319948+nathannaveen@users.noreply.github.com> Date: Fri, 17 Feb 2023 15:40:57 -0600 Subject: [PATCH 170/172] Included Wrapcheck linter (#327) * Included Wrapcheck linter Currently, a lot of errors that are returned are just returning the error and not giving any description to what the error is when debugging (ie. return err). A solution to this is to use the golang linter for wrapcheck. - Included the wrapcheck linter - Updated settings to ignore previous wrapcheck issues Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> * Updated based on code review Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> --------- Signed-off-by: nathannaveen <42319948+nathannaveen@users.noreply.github.com> --- .golangci.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 1f3aa1f7..aa2ff8e4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -11,7 +11,9 @@ issues: # Set to 0 to disable. # Default: 3 max-same-issues: 0 - new-from-rev: "" + # Exclude previously existing issues from the report + new: true + new-from-rev: HEAD linters: disable-all: true enable: @@ -59,7 +61,7 @@ linters: - unparam - unused - whitespace - #- wrapcheck + - wrapcheck linters-settings: errcheck: check-type-assertions: true From 972deecb21f08dc516d7078d5ed74e41977ef9e1 Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Thu, 23 Feb 2023 16:54:54 +1100 Subject: [PATCH 171/172] Setup goreleaser to generate Go binaries. (#331) * Setup goreleaser to generate Go binaries. Signed-off-by: Caleb Brown * Use SLSA L3 instead of just cosign. Signed-off-by: Caleb Brown --------- Signed-off-by: Caleb Brown --- .github/workflows/binary-release.yml | 58 ++++++++++++++++++++++++++++ .gitignore | 2 + .goreleaser.yaml | 58 ++++++++++++++++++++++++++++ go.sum | 6 --- 4 files changed, 118 insertions(+), 6 deletions(-) create mode 100644 .github/workflows/binary-release.yml create mode 100644 .goreleaser.yaml diff --git a/.github/workflows/binary-release.yml b/.github/workflows/binary-release.yml new file mode 100644 index 00000000..16fbf76f --- /dev/null +++ b/.github/workflows/binary-release.yml @@ -0,0 +1,58 @@ +name: binary-release + +on: + push: + tags: + - 'v*' + +permissions: + contents: read + + +jobs: + goreleaser: + runs-on: ubuntu-latest + outputs: + hashes: ${{ steps.hash.outputs.hashes }} + permissions: + contents: write # needed for goreleaser to create the release + steps: + - name: Checkout + uses: actions/checkout@ac593985615ec2ede58e132d2e21d2b1cbd6127c + with: + fetch-depth: 0 + + - name: Set up Go + uses: actions/setup-go@6edd4406fa81c3da01a34fa6f6343087c207a568 + with: + go-version: 1.19 + + - name: Run GoReleaser + id: run-goreleaser + uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Generate subject + id: hash + env: + ARTIFACTS: "${{ steps.run-goreleaser.outputs.artifacts }}" + run: | + set -euo pipefail + checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path') + echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT" + + provenance: + needs: [goreleaser] + permissions: + actions: read # To read the workflow path. + id-token: write # To sign the provenance. + contents: write # To add assets to a release. + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@68bad40844440577b33778c9f29077a3388838e9 + with: + base64-subjects: "${{ needs.goreleaser.outputs.hashes }}" + upload-assets: true # upload to a new release diff --git a/.gitignore b/.gitignore index e752351d..d0a6a54d 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,5 @@ __pycache__/ # Test output unit-coverage.out + +dist/ diff --git a/.goreleaser.yaml b/.goreleaser.yaml new file mode 100644 index 00000000..16b01a77 --- /dev/null +++ b/.goreleaser.yaml @@ -0,0 +1,58 @@ +project_name: criticality_score + +before: + hooks: + - go mod tidy + +builds: + - main: ./cmd/criticality_score + id: "criticality_score" + binary: criticality_score + flags: + - -buildvcs + env: + - CGO_ENABLED=0 + + - main: ./cmd/enumerate_github + id: "enumerate_github" + binary: enumerate_github + env: + - CGO_ENABLED=0 + + - main: ./cmd/scorer + id: "scorer" + binary: scorer + env: + - CGO_ENABLED=0 + +archives: + - id: tarballs + format: tar.gz + format_overrides: + - goos: windows + format: zip + files: + - LICENSE + - README.md + - src: cmd/criticality_score/README.md + dst: README_criticality_score.md + - src: cmd/enumerate_github/README.md + dst: README_enumerate_github.md + - src: cmd/scorer/README.md + dst: README_scorer.md + rlcp: true + +checksum: + name_template: '{{ .ProjectName }}_{{ .Version }}_checksums.txt' + +snapshot: + name_template: "{{ incpatch .Version }}-next" + +changelog: + skip: true + +release: + draft: false + +# yaml-language-server: $schema=https://goreleaser.com/static/schema.json +# vim: set ts=2 sw=2 tw=0 fo=cnqoj diff --git a/go.sum b/go.sum index 6b3fb627..0ada404d 100644 --- a/go.sum +++ b/go.sum @@ -659,8 +659,6 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220325170049-de3da57026de/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220401154927-543a649e0bdd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.2.0 h1:sZfSu1wtKLGlWI4ZZayP0ck9Y73K1ynO6gqzTdBVdPU= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= golang.org/x/net v0.4.0 h1:Q5QPcMlvfxFTAPV0+07Xz/MpK9NTXu2VDUuy0FeMfaU= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -769,8 +767,6 @@ golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220328115105-d36c6a25d886/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220330033206-e17cdc41300f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0 h1:ljd4t30dBnAvMZaQCevtY0xLLD0A+bRZXbgLMLU1F/A= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -785,8 +781,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.4.0 h1:BrVqGRd7+k1DiOgtnFvAkoQEWQvBc25ouMJM6429SFg= -golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= From 1e7ad389410ceec7bbd51a402697d0448f74aa5f Mon Sep 17 00:00:00 2001 From: Caleb Brown Date: Fri, 24 Feb 2023 13:25:47 +1100 Subject: [PATCH 172/172] Remove deprecated Python implementation. (#333) Signed-off-by: Caleb Brown --- .dockerignore | 4 - .github/dependabot.yml | 5 - .github/workflows/codeql-analysis.yml | 2 +- .gitignore | 6 - .pylintrc | 13 - criticality_score/__init__.py | 13 - criticality_score/defaults.py | 48 -- criticality_score/generate.py | 212 ------- criticality_score/run.py | 788 -------------------------- setup.py | 44 -- 10 files changed, 1 insertion(+), 1134 deletions(-) delete mode 100644 .pylintrc delete mode 100644 criticality_score/__init__.py delete mode 100644 criticality_score/defaults.py delete mode 100644 criticality_score/generate.py delete mode 100644 criticality_score/run.py delete mode 100644 setup.py diff --git a/.dockerignore b/.dockerignore index aa85271f..f4b8d71e 100644 --- a/.dockerignore +++ b/.dockerignore @@ -6,7 +6,3 @@ images # Ignore Dockerfile - this improve caching. **/Dockerfile - -# Ignore the deprecated Python project -criticality_score -*.py \ No newline at end of file diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 4e348979..66834621 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,10 +1,5 @@ version: 2 updates: -- package-ecosystem: pip - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 - package-ecosystem: gomod directory: "/" schedule: diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 96f2c8f1..0afeb316 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -28,7 +28,7 @@ jobs: strategy: fail-fast: false matrix: - language: [ 'python', 'go' ] + language: [ 'go' ] # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] # Learn more: # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed diff --git a/.gitignore b/.gitignore index d0a6a54d..d9af8792 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,6 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ - # Rope project settings .ropeproject -# Installing the package locally for development -*.egg-info - # This is for IDEs/Editors .idea diff --git a/.pylintrc b/.pylintrc deleted file mode 100644 index 948e7c26..00000000 --- a/.pylintrc +++ /dev/null @@ -1,13 +0,0 @@ -[MESSAGES CONTROL] - -disable= - broad-except, - global-statement, - missing-function-docstring, - too-many-locals, - -[MISCELLANEOUS] - -# List of note tags to take in consideration, separated by a comma. -notes= - diff --git a/criticality_score/__init__.py b/criticality_score/__init__.py deleted file mode 100644 index 6913f02e..00000000 --- a/criticality_score/__init__.py +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright 2020 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 -# -# 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. diff --git a/criticality_score/defaults.py b/criticality_score/defaults.py deleted file mode 100644 index 93ea0bcd..00000000 --- a/criticality_score/defaults.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2020 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 -# -# 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. -"""Defaults used in OSS criticality score calculation.""" -import re - -# Weights for various parameters. -CREATED_SINCE_WEIGHT = 1 -UPDATED_SINCE_WEIGHT = -1 -CONTRIBUTOR_COUNT_WEIGHT = 2 -ORG_COUNT_WEIGHT = 1 -COMMIT_FREQUENCY_WEIGHT = 1 -RECENT_RELEASES_WEIGHT = 0.5 -CLOSED_ISSUES_WEIGHT = 0.5 -UPDATED_ISSUES_WEIGHT = 0.5 -COMMENT_FREQUENCY_WEIGHT = 1 -DEPENDENTS_COUNT_WEIGHT = 2 - -# Max thresholds for various parameters. -CREATED_SINCE_THRESHOLD = 120 -UPDATED_SINCE_THRESHOLD = 120 -CONTRIBUTOR_COUNT_THRESHOLD = 5000 -ORG_COUNT_THRESHOLD = 10 -COMMIT_FREQUENCY_THRESHOLD = 1000 -RECENT_RELEASES_THRESHOLD = 26 -CLOSED_ISSUES_THRESHOLD = 5000 -UPDATED_ISSUES_THRESHOLD = 5000 -COMMENT_FREQUENCY_THRESHOLD = 15 -DEPENDENTS_COUNT_THRESHOLD = 500000 - -# Others. -TOP_CONTRIBUTOR_COUNT = 15 -ISSUE_LOOKBACK_DAYS = 90 -RELEASE_LOOKBACK_DAYS = 365 -FAIL_RETRIES = 7 - -# Regex to match dependents count. -DEPENDENTS_REGEX = re.compile(b'.*[^0-9,]([0-9,]+).*commit result', re.DOTALL) diff --git a/criticality_score/generate.py b/criticality_score/generate.py deleted file mode 100644 index 6b467ef1..00000000 --- a/criticality_score/generate.py +++ /dev/null @@ -1,212 +0,0 @@ -# Copyright 2020 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 -# -# 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. -"""Main python script for calculating OSS Criticality Score.""" - -import argparse -import csv -import logging -import os -import time - -from . import run - -logger = logging.getLogger() - -LANGUAGE_SEARCH_MAP = { - 'c': ['C'], - 'c#': ['C#'], - 'c++': ['C++'], - 'go': ['Go'], - 'java': ['Java', 'Groovy', 'Kotlin', 'Scala'], - 'js': ['Javascript', 'Typescript', 'CoffeeScript'], - 'php': ['PHP'], - 'python': ['Python'], - 'ruby': ['Ruby'], - 'rust': ['Rust'], - 'shell': ['Shell'], - 'r': ['R'], -} -IGNORED_KEYWORDS = ['docs', 'interview', 'tutorial'] -DEFAULT_SAMPLE_SIZE = 5000 - - -def get_github_repo_urls(sample_size, languages): - urls = [] - if languages: - for lang in languages: - lang = lang.lower() - for github_lang in LANGUAGE_SEARCH_MAP.get(lang, lang): - urls = get_github_repo_urls_for_language( - urls, sample_size, github_lang) - else: - urls = get_github_repo_urls_for_language(urls, sample_size) - - return urls - - -def get_github_repo_urls_for_language(urls, sample_size, github_lang=None): - """Return repository urls given a language list and sample size.""" - samples_processed = 1 - last_stars_processed = None - while samples_processed <= sample_size: - - query = 'archived:false' - if github_lang: - query += f' language:{github_lang}' - - if last_stars_processed: - # +100 to avoid any races with star updates. - query += f' stars:<{last_stars_processed+100}' - logger.info(f'Running query: {query}') - token_obj = run.get_github_auth_token() - new_result = False - repo = None - for repo in token_obj.search_repositories(query=query, - sort='stars', - order='desc'): - # Forced sleep to avoid hitting rate limit. - time.sleep(0.1) - repo_url = repo.html_url - if repo_url in urls: - # Github search can return duplicates, so skip if analyzed. - continue - if any(k in repo_url.lower() for k in IGNORED_KEYWORDS): - # Ignore uninteresting repositories. - continue - urls.append(repo_url) - new_result = True - logger.info(f'Found repository' - f'({samples_processed}): {repo_url}') - samples_processed += 1 - if samples_processed > sample_size: - break - if not new_result: - break - last_stars_processed = repo.stargazers_count - - return urls - - -def get_github_repo_urls_for_orgs(orgs): - """Return repository urls given a org list""" - repo_urls = set() - for org in orgs: - token_obj = run.get_github_auth_token() - token_org = token_obj.get_organization(org) - repos = token_org.get_repos() - for repo in repos: - repo_urls.add(repo.html_url) - - return repo_urls - - -def initialize_logging_handlers(output_dir): - log_filename = os.path.join(output_dir, 'output.log') - logging.basicConfig(filename=log_filename, - filemode='w', - level=logging.INFO) - - console = logging.StreamHandler() - console.setLevel(logging.INFO) - logging.getLogger('').addHandler(console) - - -def main(): - parser = argparse.ArgumentParser( - description= - 'Generate a sorted criticality score list for particular language(s).') - parser.add_argument("--language", - nargs='+', - default=[], - required=False, - choices=LANGUAGE_SEARCH_MAP.keys(), - help="List of languages to use.") - parser.add_argument("--output-dir", - type=str, - required=True, - help="Directory to place the output in.") - parser.add_argument("--count", - type=int, - default=10000, - help="Number of projects in result.") - parser.add_argument( - "--sample-size", - type=int, - help="Number of projects to analyze (in descending order of stars).") - parser.add_argument("--org", - nargs='+', - default=[], - required=False, - help="List of organizations for populating the repos.") - - args = parser.parse_args() - - initialize_logging_handlers(args.output_dir) - - repo_urls = set() - if args.org: - assert not args.language, 'Languages is not supported with orgs.' - assert not args.sample_size, 'Sample size is not supported with orgs.' - repo_urls.update(get_github_repo_urls_for_orgs(args.org)) - else: - if not args.sample_size: - args.sample_size = DEFAULT_SAMPLE_SIZE - # GitHub search can return incomplete results in a query, so try it - # multiple times to avoid missing urls. - for rnd in range(1, 4): - logger.info(f'Finding repos (round {rnd}):') - repo_urls.update( - get_github_repo_urls(args.sample_size, args.language)) - - stats = [] - index = 1 - for repo_url in sorted(repo_urls): - output = None - for _ in range(3): - try: - repo = run.get_repository(repo_url) - if not repo: - logger.error(f'Repo is not found: {repo_url}') - break - output = run.get_repository_stats(repo) - break - except Exception as exp: - logger.exception( - f'Exception occurred when reading repo: {repo_url}\n{exp}') - if not output: - continue - logger.info(f"{index} - {output['name']} - {output['url']} - " - f"{output['criticality_score']}") - stats.append(output) - index += 1 - - if len(stats) == 0: - return - languages = '_'.join(args.language) if args.language else 'all' - languages = languages.replace('+', 'plus').replace('c#', 'csharp') - output_filename = os.path.join(args.output_dir, - f'{languages}_top_{args.count}.csv') - with open(output_filename, 'w') as file_handle: - csv_writer = csv.writer(file_handle) - header = output.keys() - csv_writer.writerow(header) - for i in sorted(stats, - key=lambda i: i['criticality_score'], - reverse=True)[:args.count]: - csv_writer.writerow(i.values()) - logger.info(f'Wrote results: {output_filename}') - - -if __name__ == "__main__": - main() diff --git a/criticality_score/run.py b/criticality_score/run.py deleted file mode 100644 index 9851c69a..00000000 --- a/criticality_score/run.py +++ /dev/null @@ -1,788 +0,0 @@ -# Copyright 2020 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 -# -# 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. -"""Main python script for calculating OSS Criticality Score.""" - -import argparse -import csv -import datetime -import json -import logging -import math -import os -import sys -import threading -import time -import urllib -import warnings - -import github -import gitlab -import requests - -from .defaults import * # pylint: disable=wildcard-import - - -logger = logging.getLogger() - -_DEPRECATION_MESSAGE = """ -The python version of criticality-score is deprecated and will -no longer receive updates. - -A Go version exists and is under active development and should be used instead. -See https://github.com/ossf/criticality_score for more details. -""" -warnings.simplefilter("always", DeprecationWarning) -warnings.warn(_DEPRECATION_MESSAGE, DeprecationWarning) - -_CACHED_GITHUB_TOKEN = None -_CACHED_GITHUB_TOKEN_OBJ = None - -PARAMS = [ - 'description', 'created_since', 'updated_since', 'contributor_count', 'watchers_count', 'org_count', - 'commit_frequency', 'recent_releases_count', 'updated_issues_count', - 'closed_issues_count', 'comment_frequency', 'dependents_count' -] - - -class Repository: - """General source repository.""" - def __init__(self, repo): - self._repo = repo - self._last_commit = None - self._created_since = None - - @property - def name(self): - raise NotImplementedError - - @property - def url(self): - raise NotImplementedError - - @property - def language(self): - raise NotImplementedError - - @property - def description(self): - raise NotImplementedError - - @property - def last_commit(self): - raise NotImplementedError - - @property - def created_since(self): - raise NotImplementedError - - @property - def updated_since(self): - raise NotImplementedError - - @property - def contributor_count(self): - raise NotImplementedError - - @property - def watchers_count(self): - raise NotImplementedError - - @property - def org_count(self): - raise NotImplementedError - - @property - def commit_frequency(self): - raise NotImplementedError - - @property - def recent_releases_count(self): - raise NotImplementedError - - @property - def updated_issues_count(self): - raise NotImplementedError - - @property - def closed_issues_count(self): - raise NotImplementedError - - @property - def comment_frequency(self): - raise NotImplementedError - - def _request_url_with_auth_headers(self, url): - headers = {} - if 'github.com' in url and _CACHED_GITHUB_TOKEN: - headers = {'Authorization': f'token {_CACHED_GITHUB_TOKEN}'} - - return requests.get(url, headers=headers) - - @property - def dependents_count(self): - # TODO: Take package manager dependency trees into account. If we decide - # to replace this, then find a solution for C/C++ as well. - match = None - parsed_url = urllib.parse.urlparse(self.url) - repo_name = parsed_url.path.strip('/') - dependents_url = ( - f'https://github.com/search?q="{repo_name}"&type=commits') - for i in range(FAIL_RETRIES): - result = self._request_url_with_auth_headers(dependents_url) - if result.status_code == 200: - match = DEPENDENTS_REGEX.match(result.content) - break - time.sleep(2**i) - if not match: - return 0 - return int(match.group(1).replace(b',', b'')) - - -class GitHubRepository(Repository): - """Source repository hosted on GitHub.""" - # General metadata attributes. - @property - def name(self): - return self._repo.name - - @property - def url(self): - return self._repo.html_url - - @property - def language(self): - return self._repo.language - - @property - def description(self): - return self._repo.description - - @property - def last_commit(self): - if self._last_commit: - return self._last_commit - try: - self._last_commit = self._repo.get_commits()[0] - except Exception: - pass - return self._last_commit - - def get_first_commit_time(self): - def _parse_links(response): - link_string = response.headers.get('Link') - if not link_string: - return None - - links = {} - for part in link_string.split(','): - match = re.match(r'<(.*)>; rel="(.*)"', part.strip()) - if match: - links[match.group(2)] = match.group(1) - return links - - for i in range(FAIL_RETRIES): - result = self._request_url_with_auth_headers( - f'{self._repo.url}/commits') - links = _parse_links(result) - if links and links.get('last'): - result = self._request_url_with_auth_headers(links['last']) - if result.status_code == 200: - commits = json.loads(result.content) - if commits: - last_commit_time_string = ( - commits[-1]['commit']['committer']['date']) - return datetime.datetime.strptime(last_commit_time_string, - "%Y-%m-%dT%H:%M:%SZ") - time.sleep(2**i) - - return None - - # Criteria important for ranking. - @property - def created_since(self): - if self._created_since: - return self._created_since - - creation_time = self._repo.created_at - - # See if there are exist any commits before this repository creation - # time on GitHub. If yes, then the repository creation time is not - # correct, and it was residing somewhere else before. So, use the first - # commit date. - if self._repo.get_commits(until=creation_time).totalCount: - first_commit_time = self.get_first_commit_time() - if first_commit_time: - creation_time = min(creation_time, first_commit_time) - - difference = datetime.datetime.utcnow() - creation_time - self._created_since = round(difference.days / 30) - return self._created_since - - @property - def updated_since(self): - last_commit_time = self.last_commit.commit.author.date - difference = datetime.datetime.utcnow() - last_commit_time - return round(difference.days / 30) - - @property - def contributor_count(self): - try: - return self._repo.get_contributors(anon='true').totalCount - except Exception: - # Very large number of contributors, i.e. 5000+. Cap at 5,000. - return 5000 - - @property - def watchers_count(self): - return self._repo.watchers_count - - @property - def org_count(self): - def _filter_name(org_name): - return org_name.lower().replace('inc.', '').replace( - 'llc', '').replace('@', '').replace(' ', '').rstrip(',') - - orgs = set() - contributors = self._repo.get_contributors()[:TOP_CONTRIBUTOR_COUNT] - try: - for contributor in contributors: - if contributor.company: - orgs.add(_filter_name(contributor.company)) - except Exception: - # Very large number of contributors, i.e. 5000+. Cap at 10. - return 10 - return len(orgs) - - @property - def commit_frequency(self): - total = 0 - for week_stat in self._repo.get_stats_commit_activity(): - total += week_stat.total - return round(total / 52, 1) - - @property - def recent_releases_count(self): - total = 0 - for release in self._repo.get_releases(): - if (datetime.datetime.utcnow() - - release.created_at).days > RELEASE_LOOKBACK_DAYS: - continue - total += 1 - if not total: - # Make rough estimation of tags used in last year from overall - # project history. This query is extremely expensive, so instead - # do the rough calculation. - days_since_creation = self.created_since * 30 - if not days_since_creation: - return 0 - total_tags = 0 - try: - total_tags = self._repo.get_tags().totalCount - except Exception: - # Very large number of tags, i.e. 5000+. Cap at 26. - logger.error(f'get_tags is failed: {self._repo.url}') - return RECENT_RELEASES_THRESHOLD - total = round( - (total_tags / days_since_creation) * RELEASE_LOOKBACK_DAYS) - return total - - @property - def updated_issues_count(self): - issues_since_time = datetime.datetime.utcnow() - datetime.timedelta( - days=ISSUE_LOOKBACK_DAYS) - return self._repo.get_issues(state='all', - since=issues_since_time).totalCount - - @property - def closed_issues_count(self): - issues_since_time = datetime.datetime.utcnow() - datetime.timedelta( - days=ISSUE_LOOKBACK_DAYS) - return self._repo.get_issues(state='closed', - since=issues_since_time).totalCount - - @property - def comment_frequency(self): - issues_since_time = datetime.datetime.utcnow() - datetime.timedelta( - days=ISSUE_LOOKBACK_DAYS) - issue_count = self._repo.get_issues(state='all', - since=issues_since_time).totalCount - if not issue_count: - return 0 - comment_count = self._repo.get_issues_comments( - since=issues_since_time).totalCount - return round(comment_count / issue_count, 1) - - -class GitLabRepository(Repository): - """Source repository hosted on GitLab.""" - @staticmethod - def _date_from_string(date_string): - return datetime.datetime.strptime(date_string, - "%Y-%m-%dT%H:%M:%S.%f%z") - - @property - def name(self): - return self._repo.name - - @property - def url(self): - return self._repo.web_url - - @property - def language(self): - languages = self._repo.languages() - return (max(languages, key=languages.get)).lower() - - @property - def last_commit(self): - if self._last_commit: - return self._last_commit - self._last_commit = next(iter(self._repo.commits.list()), None) - return self._last_commit - - @property - def created_since(self): - creation_time = self._date_from_string(self._repo.created_at) - commit = None - for commit in self._repo.commits.list(until=creation_time, - as_list=False): - pass - if commit: - creation_time = self._date_from_string(commit.created_at) - difference = datetime.datetime.now( - datetime.timezone.utc) - creation_time - return round(difference.days / 30) - - @property - def updated_since(self): - difference = datetime.datetime.now( - datetime.timezone.utc) - self._date_from_string( - self.last_commit.created_at) - return round(difference.days / 30) - - @property - def contributor_count(self): - return len(self._repo.repository_contributors(all=True)) - - @property - def org_count(self): - # Not possible to calculate as this feature restricted to admins only. - # https://docs.gitlab.com/ee/api/users.html#user-memberships-admin-only - return 1 - - @property - def commit_frequency(self): - commits_since_time = datetime.datetime.utcnow() - datetime.timedelta( - days=365) - iterator = self._repo.commits.list(since=commits_since_time, - as_list=False) - commits_count = sum(1 for _ in iterator) - return round(commits_count / 52, 1) - - @property - def recent_releases_count(self): - count = 0 - for release in self._repo.releases.list(): - release_time = self._date_from_string(release.released_at) - if (datetime.datetime.now(datetime.timezone.utc) - - release_time).days > RELEASE_LOOKBACK_DAYS: - break - count += 1 - count = 0 - if not count: - for tag in self._repo.tags.list(): - tag_time = self._date_from_string(tag.commit['created_at']) - if (datetime.datetime.now(datetime.timezone.utc) - - tag_time).days > RELEASE_LOOKBACK_DAYS: - break - count += 1 - return count - - @property - def updated_issues_count(self): - issues_since_time = datetime.datetime.utcnow() - datetime.timedelta( - days=ISSUE_LOOKBACK_DAYS) - return self._repo.issuesstatistics.get( - updated_after=issues_since_time).statistics['counts']['all'] - - @property - def closed_issues_count(self): - issues_since_time = datetime.datetime.utcnow() - datetime.timedelta( - days=ISSUE_LOOKBACK_DAYS) - return self._repo.issuesstatistics.get( - updated_after=issues_since_time).statistics['counts']['closed'] - - @property - def comment_frequency(self): - comments_count = 0 - issues_since_time = datetime.datetime.utcnow() - datetime.timedelta( - days=ISSUE_LOOKBACK_DAYS) - for issue in self._repo.issues.list(updated_after=issues_since_time, - as_list=False): - try: - comments_count += issue.notes.list(as_list=False).total - except Exception: - pass - return round(comments_count / self.updated_issues_count, 1) - - -def get_param_score(param, max_value, weight=1): - """Return paramater score given its current value, max value and - parameter weight.""" - return (math.log(1 + param) / math.log(1 + max(param, max_value))) * weight - - -def get_repository_stats(repo): - """Return repository stats by grabing the raw signal data from the repo.""" - if not repo.last_commit: - logger.error(f'Repo is empty: {repo.url}') - return None - - def _worker(repo, param, return_dict): - """worker function""" - return_dict[param] = getattr(repo, param) - - threads = [] - return_dict = {} - for param in PARAMS: - thread = threading.Thread(target=_worker, - args=(repo, param, return_dict)) - thread.start() - threads.append(thread) - for thread in threads: - thread.join() - - # Guarantee insertion order. - result_dict = { - 'name': repo.name, - 'url': repo.url, - 'language': repo.language, - } - for param in PARAMS: - result_dict[param] = return_dict[param] - - return result_dict - - -def get_repository_score(repo_stats, additional_params=None): - """Return one repository's criticality score based on repo stats.""" - # Validate and compute additional params first. - if additional_params is None: - additional_params = [] - additional_params_total_weight = 0 - additional_params_score = 0 - for additional_param in additional_params: - try: - value, weight, max_threshold = [ - float(i) for i in additional_param.split(':') - ] - except ValueError: - logger.error('Parameter value in bad format: ' + additional_param) - sys.exit(1) - additional_params_total_weight += weight - additional_params_score += get_param_score(value, max_threshold, - weight) - - total_weight = (CREATED_SINCE_WEIGHT + UPDATED_SINCE_WEIGHT + - CONTRIBUTOR_COUNT_WEIGHT + ORG_COUNT_WEIGHT + - COMMIT_FREQUENCY_WEIGHT + RECENT_RELEASES_WEIGHT + - CLOSED_ISSUES_WEIGHT + UPDATED_ISSUES_WEIGHT + - COMMENT_FREQUENCY_WEIGHT + DEPENDENTS_COUNT_WEIGHT + - additional_params_total_weight) - - criticality_score = round( - ((get_param_score(float(repo_stats['created_since']), - CREATED_SINCE_THRESHOLD, CREATED_SINCE_WEIGHT)) + - (get_param_score(float(repo_stats['updated_since']), - UPDATED_SINCE_THRESHOLD, UPDATED_SINCE_WEIGHT)) + - (get_param_score(float(repo_stats['contributor_count']), - CONTRIBUTOR_COUNT_THRESHOLD, CONTRIBUTOR_COUNT_WEIGHT)) + - (get_param_score(float(repo_stats['org_count']), - ORG_COUNT_THRESHOLD, ORG_COUNT_WEIGHT)) + - (get_param_score(float(repo_stats['commit_frequency']), - COMMIT_FREQUENCY_THRESHOLD, COMMIT_FREQUENCY_WEIGHT)) + - (get_param_score(float(repo_stats['recent_releases_count']), - RECENT_RELEASES_THRESHOLD, RECENT_RELEASES_WEIGHT)) + - (get_param_score(float(repo_stats['closed_issues_count']), - CLOSED_ISSUES_THRESHOLD, CLOSED_ISSUES_WEIGHT)) + - (get_param_score(float(repo_stats['updated_issues_count']), - UPDATED_ISSUES_THRESHOLD, UPDATED_ISSUES_WEIGHT)) + - (get_param_score(float(repo_stats['comment_frequency']), - COMMENT_FREQUENCY_THRESHOLD, COMMENT_FREQUENCY_WEIGHT)) + - (get_param_score(float(repo_stats['dependents_count']), - DEPENDENTS_COUNT_THRESHOLD, DEPENDENTS_COUNT_WEIGHT)) + - additional_params_score) / - total_weight, 5) - - # Make sure score between 0 (least-critical) and 1 (most-critical). - criticality_score = max(min(criticality_score, 1), 0) - - return criticality_score - - -def get_repository_score_from_raw_stats(repo_url, params=None): - """Get repository's criticality_score based on raw signal data.""" - repo = get_repository(repo_url) - if repo is None: - logger.error(f'Repo is not found: {repo_url}') - return - repo_stats = get_repository_stats(repo) - repo_stats["criticality_score"] = get_repository_score(repo_stats, params) - - return repo_stats - - -def get_repository_score_from_local_csv(file_path, params=None): - """Get repository's criticality_score based on a local csv file.""" - if params is None: - additional_params = [] - else: - try: - additional_params = [additional_param.split(':') for additional_param in params] - except ValueError: - logger.error('Parameter value in bad format: ' + params) - sys.exit(1) - - output = [] - with open(file_path, "r") as fd: - input_data = csv.DictReader(fd, delimiter=',') - for row in input_data: - logger.debug(row) - - calc_params = [] - for key,weight,max_threshold in additional_params: - calc_params.append(f"{row[key]}:{weight}:{max_threshold}") - - row["criticality_score"] = get_repository_score(row, calc_params) - output.append(row) - - return output - - -def get_github_token_info(token_obj): - """Return expiry information given a github token.""" - rate_limit = token_obj.get_rate_limit() - near_expiry = rate_limit.core.remaining < 50 - wait_time = (rate_limit.core.reset - datetime.datetime.utcnow()).seconds - return near_expiry, wait_time - - -def get_github_auth_token(): - """Return an un-expired github token if possible from a list of tokens.""" - global _CACHED_GITHUB_TOKEN - global _CACHED_GITHUB_TOKEN_OBJ - if _CACHED_GITHUB_TOKEN_OBJ: - near_expiry, _ = get_github_token_info(_CACHED_GITHUB_TOKEN_OBJ) - if not near_expiry: - return _CACHED_GITHUB_TOKEN_OBJ - - github_auth_token = os.getenv('GITHUB_AUTH_TOKEN') - assert github_auth_token, 'GITHUB_AUTH_TOKEN needs to be set.' - tokens = github_auth_token.split(',') - - min_wait_time = None - token_obj = None - for token in tokens: - token_obj = github.Github(token) - near_expiry, wait_time = get_github_token_info(token_obj) - if not min_wait_time or wait_time < min_wait_time: - min_wait_time = wait_time - if not near_expiry: - _CACHED_GITHUB_TOKEN = token - _CACHED_GITHUB_TOKEN_OBJ = token_obj - return token_obj - - logger.warning( - f'Rate limit exceeded, sleeping till reset: {round(min_wait_time / 60, 1)} minutes.' - ) - time.sleep(min_wait_time) - return token_obj - - -def get_gitlab_auth_token(host): - """Return a gitlab token object.""" - gitlab_auth_token = os.getenv('GITLAB_AUTH_TOKEN') - try: - token_obj = gitlab.Gitlab(host, gitlab_auth_token) - token_obj.auth() - except gitlab.exceptions.GitlabAuthenticationError: - logger.info("Auth token didn't work, trying un-authenticated. " - "Some params like comment_frequency will not work.") - token_obj = gitlab.Gitlab(host) - return token_obj - - -def get_repository(url): - """Return repository object, given a url.""" - if not '://' in url: - url = 'https://' + url - - parsed_url = urllib.parse.urlparse(url) - repo_url = parsed_url.path.strip('/') - if parsed_url.netloc.endswith('github.com'): - repo = None - try: - repo = get_github_auth_token().get_repo(repo_url) - except github.GithubException as exp: - logger.error(f"Get github repository failed: {exp}") - if exp.status == 404: - return None - return GitHubRepository(repo) - if 'gitlab' in parsed_url.netloc: - repo = None - host = parsed_url.scheme + '://' + parsed_url.netloc - token_obj = get_gitlab_auth_token(host) - repo_url_encoded = urllib.parse.quote_plus(repo_url) - try: - repo = token_obj.projects.get(repo_url_encoded) - except gitlab.exceptions.GitlabGetError as exp: - if exp.response_code == 404: - return None - return GitLabRepository(repo) - - raise Exception('Unsupported url!') - - -def initialize_logging_handlers(): - logging.basicConfig(level=logging.INFO) - logging.getLogger('').handlers.clear() - - console = logging.StreamHandler() - console.setLevel(logging.INFO) - logging.getLogger('').addHandler(console) - - -def override_params(override_params): - for override_param in override_params: - temp = override_param.split(':',1) - param_name = temp[0] - try: - weight, threshold = [ - float(i) for i in temp[1].split(':') - ] - except ValueError: - logger.error('Override parameter in bad format: ' + override_param) - sys.exit(1) - if param_name == 'created_since': - global CREATED_SINCE_WEIGHT, CREATED_SINCE_THRESHOLD - CREATED_SINCE_WEIGHT = weight - CREATED_SINCE_THRESHOLD = threshold - elif param_name == 'updated_since': - global UPDATED_SINCE_WEIGHT, UPDATED_SINCE_THRESHOLD - UPDATED_SINCE_WEIGHT = weight - UPDATED_SINCE_THRESHOLD = threshold - elif param_name == 'contributor_count': - global CONTRIBUTOR_COUNT_WEIGHT, CONTRIBUTOR_COUNT_THRESHOLD - CONTRIBUTOR_COUNT_WEIGHT = weight - CONTRIBUTOR_COUNT_THRESHOLD = threshold - elif param_name == 'org_count': - global ORG_COUNT_WEIGHT, ORG_COUNT_THRESHOLD - ORG_COUNT_WEIGHT = weight - ORG_COUNT_THRESHOLD = threshold - elif param_name == 'commit_frequency': - global COMMIT_FREQUENCY_WEIGHT, COMMIT_FREQUENCY_THRESHOLD - COMMIT_FREQUENCY_WEIGHT = weight - COMMIT_FREQUENCY_THRESHOLD = threshold - elif param_name == 'recent_releases_count': - global RECENT_RELEASES_WEIGHT, RECENT_RELEASES_THRESHOLD - RECENT_RELEASES_WEIGHT = weight - RECENT_RELEASES_THRESHOLD = threshold - elif param_name == 'updated_issues_count': - global UPDATED_ISSUES_WEIGHT, UPDATED_ISSUES_THRESHOLD - UPDATED_ISSUES_WEIGHT = weight - UPDATED_ISSUES_THRESHOLD = threshold - elif param_name == 'closed_issues_count': - global CLOSED_ISSUES_WEIGHT, CLOSED_ISSUES_THRESHOLD - CLOSED_ISSUES_WEIGHT = weight - CLOSED_ISSUES_THRESHOLD = threshold - elif param_name == 'comment_frequency': - global COMMENT_FREQUENCY_WEIGHT, COMMENT_FREQUENCY_THRESHOLD - COMMENT_FREQUENCY_WEIGHT = weight - COMMENT_FREQUENCY_THRESHOLD = threshold - elif param_name == 'dependents_count': - global DEPENDENTS_COUNT_WEIGHT, DEPENDENTS_COUNT_THRESHOLD - DEPENDENTS_COUNT_WEIGHT = weight - DEPENDENTS_COUNT_THRESHOLD = threshold - else: - raise Exception( - 'Wrong format argument, unknown parameter: ' + param_name) - - -def main(): - parser = argparse.ArgumentParser( - description='Gives criticality score for an open source project') - group = parser.add_mutually_exclusive_group(required=True) - group.add_argument("--repo", - type=str, - help="repository url") - group.add_argument("--local-file", - type=str, - dest="l_file", - help="path of a local csv file with repo stats") - parser.add_argument( - "--format", - type=str, - default='default', - choices=['default', 'csv', 'json'], - help="output format. allowed values are [default, csv, json]") - parser.add_argument( - '--params', - nargs='+', - default=[], - help='Additional parameters in form (|)::, for repo, and for loacl file', - required=False) - parser.add_argument( - '--overrides', - nargs='+', - default=[], - help='Overriding parameters in form ::', - required=False) - - initialize_logging_handlers() - args = parser.parse_args() - if args.overrides: - override_params(args.overrides) - - output = None - if args.repo: - output = get_repository_score_from_raw_stats(args.repo, args.params) - elif args.l_file: - if args.format != "csv": - logger.error(f"Only support for the format of csv, now is {args.format}") - sys.exit(1) - - output = get_repository_score_from_local_csv(args.l_file, args.params) - else: - raise Exception("Unknown data input type") - - if output is None: - return - if args.format == 'default': - for key, value in output.items(): - logger.info(f'{key}: {value}') - elif args.format == 'json': - logger.info(json.dumps(output, indent=4)) - elif args.format == 'csv': - if args.repo: - output = [output] - csv_writer = csv.DictWriter(sys.stdout, fieldnames=output[0].keys()) - csv_writer.writeheader() - csv_writer.writerows(output) - else: - raise Exception( - 'Wrong format argument, use one of default, csv or json!') - - -if __name__ == "__main__": - main() diff --git a/setup.py b/setup.py deleted file mode 100644 index 731a58bc..00000000 --- a/setup.py +++ /dev/null @@ -1,44 +0,0 @@ -# Copyright 2020 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 -# -# 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. -"""setup.py for OSS Criticality Score.""" -import setuptools - -with open('README.md', 'r') as fh: - long_description = fh.read() - -setuptools.setup( - name='criticality_score', - version='1.0.8', - author='Abhishek Arya', - author_email='', - description='Gives criticality score for an open source project', - long_description=long_description, - long_description_content_type='text/markdown', - url='https://github.com/ossf/criticality-score', - packages=setuptools.find_packages(include=["criticality_score"]), - classifiers=[ - 'Programming Language :: Python :: 3', - 'License :: OSI Approved :: Apache Software License', - 'Operating System :: OS Independent', - ], - install_requires=[ - 'PyGithub>=1.53', - 'python-gitlab>=2.5.0', - ], - entry_points={ - 'console_scripts': ['criticality_score=criticality_score.run:main'], - }, - python_requires='>=3.6', - zip_safe=False, -)