Full Code of reposaur/reposaur for AI

main ba8af4048815 cached
42 files
117.1 KB
46.4k tokens
113 symbols
1 requests
Download .txt
Repository: reposaur/reposaur
Branch: main
Commit: ba8af4048815
Files: 42
Total size: 117.1 KB

Directory structure:
gitextract_j1gkgj0k/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.yml
│   ├── codeowners
│   ├── dependabot.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .goreleaser.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── Taskfile.yaml
├── action.yml
├── cmd/
│   └── rsr/
│       ├── internal/
│       │   ├── bundle/
│       │   │   └── bundle.go
│       │   ├── cmdutil/
│       │   │   ├── env.go
│       │   │   ├── flag.go
│       │   │   ├── io.go
│       │   │   └── logger.go
│       │   ├── exec/
│       │   │   └── exec.go
│       │   ├── root/
│       │   │   └── root.go
│       │   └── test/
│       │       └── test.go
│       └── rsr.go
├── go.mod
├── go.sum
├── install.sh
├── internal/
│   ├── build/
│   │   └── build.go
│   └── policy/
│       ├── engine.go
│       └── errors.go
├── pkg/
│   ├── output/
│   │   ├── report.go
│   │   └── sarif.go
│   └── sdk/
│       └── sdk.go
├── provider/
│   ├── github/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── github.go
│   │   ├── github_test.go
│   │   └── internal/
│   │       └── builtin/
│   │           ├── graphql.go
│   │           ├── request.go
│   │           └── response.go
│   ├── provider.go
│   └── provider_test.go
└── scripts/
    └── completions.sh

================================================
FILE CONTENTS
================================================

================================================
FILE: .github/FUNDING.yml
================================================
github: [reposaur, crqra]


================================================
FILE: .github/ISSUE_TEMPLATE/bug_report.yml
================================================
name: Bug Report
description: File a bug report

title: "[Bug]: "
labels: ["bug", "triage"]

body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to fill out this bug report and improving Reposaur!

  - type: textarea
    id: description
    attributes:
      label: Description
      description: Describe what happened
      placeholder: Tell us what you see!
    validations:
      required: true

  - type: textarea
    id: expected
    attributes:
      label: Expectation
      description: Describe what you expected to have happened
      placeholder: Tell us what you expected to see!
    validations:
      required: true

  - type: input
    id: version
    attributes:
      label: Version
      description: What's the version of Reposaur you're running?
      placeholder: 0.0.0

  - type: textarea
    id: logs
    attributes:
      label: Relevant log output
      description: |
        Please copy and paste any relevant log output.
        This will be automatically formatted into code, so no need for backticks.
      render: shell

  - type: checkboxes
    id: terms
    attributes:
      label: Code of Conduct
      description: |
        By submitting this issue, you agree to follow our
        [Code of Conduct](https://github.com/reposaur/reposaur/blob/main/CODE_OF_CONDUCT.md)
      options:
        - label: I agree to follow Reposaur's Code of Conduct
          required: true


================================================
FILE: .github/ISSUE_TEMPLATE/config.yml
================================================
blank_issues_enabled: true
contact_links:
  - name: Ask a question
    url: https://github.com/orgs/reposaur/discussions
    about: Community Support Forum


================================================
FILE: .github/ISSUE_TEMPLATE/feature_request.yml
================================================
name: Feature Request
description: Suggest a new idea or feature to add to Reposaur

title: "[Feature]: "
labels: ["enhancement", "triage"]

body:
  - type: markdown
    attributes:
      value: |
        Thanks for taking the time to suggest new ideas and features,
        improving Reposaur!

  - type: textarea
    id: description
    attributes:
      label: What would you like to see improved?
      description: |
        Is there something challenging or frustrating about Reposaur
        that you're trying to improve? How would this improvement make your
        experience better?
    validations:
      required: true

  - type: textarea
    id: ideal-solution
    attributes:
      label: What would be the ideal solution?
    validations:
      required: true

  - type: textarea
    id: good-solution
    attributes:
      label: What would be a \"good enough\" solution?
    validations:
      required: true

  - type: checkboxes
    id: terms
    attributes:
      label: Code of Conduct
      description: |
        By submitting this issue, you agree to follow our
        [Code of Conduct](https://github.com/reposaur/reposaur/blob/main/CODE_OF_CONDUCT.md)
      options:
        - label: I agree to follow Reposaur's Code of Conduct
          required: true


================================================
FILE: .github/codeowners
================================================
* @crqra

================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "weekly"


================================================
FILE: .github/workflows/test.yml
================================================
name: Test

on:
  push:
    branches:
      - main
  pull_request:

env:
  GO111MODULE: on

jobs:
  golangci-lint:
    name: Golang CI Lint
    runs-on: ubuntu-latest
    steps:
      - name: Setup Go
        uses: actions/setup-go@v2
        with:
          go-version: "1.18"

      - name: Checkout
        uses: actions/checkout@v3

      - name: Golang CI Lint
        uses: golangci/golangci-lint-action@v3.1.0
        with:
          version: latest
          args: --verbose

  test-unix:
    strategy:
      fail-fast: false
      matrix:
        platform:
          - ubuntu
          - macOS
        go:
          - 18
    name: "${{ matrix.platform }} | 1.${{ matrix.go }}.x"
    runs-on: ${{ matrix.platform }}-latest
    steps:
      - name: Setup Go
        uses: actions/setup-go@v2
        with:
          go-version: 1.${{ matrix.go }}.x

      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Cache
        uses: actions/cache@v3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-1.${{ matrix.go }}.x-${{ hashFiles('**/go.sum') }}
          restore-keys: ${{ runner.os }}-1.${{ matrix.go }}.x-

      - name: Test
        run: go test ./...

  test-win:
    name: MINGW64
    defaults:
      run:
        shell: msys2 {0}
    runs-on: windows-latest
    steps:
      - name: Setup MSYS2
        uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          update: true
          install: >
            git
            make
            unzip
            mingw-w64-x86_64-go

      - name: Checkout
        uses: actions/checkout@v3

      - name: Setup Cache
        uses: actions/cache@v3
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-${{ matrix.go }}-${{ hashFiles('**/go.sum') }}
          restore-keys: ${{ runner.os }}-${{ matrix.go }}-

      - name: Test
        run: go test ./...


================================================
FILE: .gitignore
================================================
# Used for local tests only
/config.yaml
/policy/
/testdata/events/_*.json
dist/
bin/

# Generated
/completions

# Editors
/.idea
/.vscode
/.fleet

================================================
FILE: .goreleaser.yml
================================================
before:
  hooks:
    - go mod tidy
    - go vet ./...
    - ./scripts/completions.sh

builds:
  - id: rsr
    binary: rsr
    main: ./cmd/rsr/rsr.go
    ldflags:
      - -s -w -X github.com/reposaur/reposaur/internal/build.Version={{.Version}}
    env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin
  - id: reposaur
    binary: reposaur
    main: ./cmd/rsr/rsr.go
    ldflags:
      - -s -w -X github.com/reposaur/reposaur/internal/build.Version={{.Version}}
    env:
      - CGO_ENABLED=0
    goos:
      - linux
      - windows
      - darwin

archives:
  - replacements:
      darwin: Darwin
      linux: Linux
      windows: Windows
      386: i386
      amd64: x86_64
    format_overrides:
      - goos: windows
        format: zip
    files:
      - README.md
      - LICENSE
      - completions/*

checksum:
  name_template: "checksums.txt"

snapshot:
  name_template: "{{ incpatch .Version }}-next"

changelog:
  use: github
  sort: asc
  filters:
    exclude:
      - "^test:"
      - "^chore:"
      - "^build:"
  groups:
    - title: 'New Features and updates'
      regexp: "^.*feat[(\\w)]*:+.*$"
      order: 0
    - title: 'Bug fixes'
      regexp: "^.*fix[(\\w)]*:+.*$"
      order: 10
    - title: 'Documentation updates'
      regexp: "^.*docs[(\\w)]*:+.*$"
      order: 20
    - title: Other work
      order: 999

release:
  github:
    owner: reposaur
    name: reposaur
  prerelease: auto
  footer: |
    **Full Changelog**: https://github.com/reposaur/reposaur/compare/{{ .PreviousTag }}...{{ .Tag }}

    ## What to do next?

    - Read the [documentation](https://docs.reposaur.com)
    - Join our [Slack](https://slack.reposaur.com)
    - Follow us on [Twitter](https://twitter.com/reposaurhq)

brews:
  - tap:
      owner: reposaur
      name: homebrew-tap
    commit_author:
      name: goreleaserbot
      email: goreleaser@carlosbecker.com
    commit_msg_template: "chore: brew formula update for {{ .ProjectName }} version {{ .Tag }}"
    folder: Formula
    homepage: "https://reposaur.com"
    description: "Open source compliance tool for development platforms"
    license: "MIT"
    test: |
      system "#{bin}/rsr"
    install: |-
      bin.install "rsr"
      bash_completion.install "completions/rsr.bash" => "rsr"
      zsh_completion.install "completions/rsr.zsh" => "_rsr"
      fish_completion.install "completions/rsr.fish"

nfpms:
  - vendor: Reposaur
    homepage: https://reposaur.com/
    maintainer: João Cerqueira <oss@cerqueira.io>
    description: |-
      The open source compliance tool for development platforms.
    license: MIT
    contents:
      - src: ./completions/rsr.bash
        dst: /usr/share/bash-completion/completions/rsr
        file_info:
          mode: 0644
      - src: ./completions/rsr.fish
        dst: /usr/share/fish/completions/rsr.fish
        file_info:
          mode: 0644
      - src: ./completions/rsr.zsh
        dst:  /usr/share/zsh/vendor-completions/_rsr
        file_info:
          mode: 0644
      - src: ./LICENSE
        dst: /usr/share/doc/rsr/copyright
        file_info:
          mode: 0644
    formats:
      - apk
      - deb
      - rpm
    section: utils
    priority: extra


================================================
FILE: CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
  overall community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or
  advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
  address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.

Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
oss@cerqueira.io.
All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident.

## Enforcement Guidelines

Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series
of actions.

**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior,  harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within
the community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.

Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.


================================================
FILE: CONTRIBUTING.md
================================================
# Contributing

Beforehand, thank you for considering contributing to Reposaur! We welcome and
appreciate any help we can get.

Contributors are expected to follow our [Code of Conduct](CODE_OF_CONDUCT.md).

## Feedback and Questions

We appreciate any feedback we can get and are happy to answer any questions you
might have!

Reach out to us in [Discussions][discussions] or in our [Slack Workspace][slack].

## Bug Reporting and Feature Requests

### Bug Reports

If you've found an issue in the CLI, SDK or Policy Engine, please
[open a bug report][bug-report]. We appreciate the feedback and will try to help
as soon as possible. The form will guide you on how to report the bug.

### Feature Requests

If you've an exiting idea, new use case or anything else, we'd love to hear it!
Please, [open a feature request][feature-request] and share it with the community!
The form will guide you on how to request a new feature.

## Development

To get your development environment ready you'll need to have the following
installed:

- [Go][go] >= 1.18
- [Task][task] >= 3.0

### Setting up

Fork the repository to your account and clone it to your machine. Build for the
first time and make sure everything is working as expected:

```console
$ task build
```

If you don't have Task installed you can issue the following commands:

```console
go mod tidy
go build -o ./.bin/rsr ./cmd/rsr/rsr.go \
    -ldflags "-s -w -X github.com/reposaur/reposaur/internal/build.Version=devel"
```

After the command above you should have `rsr` available in `./.bin`:

```console
$ ./.bin/rsr --version
rsr version devel
```

Happy coding!

### Creating a Pull Request

We don't have any rigid structure for Pull Requests right now, although that's
expected to change in the future.

For now, just explain briefly what your changes address and link any related
issues or other Pull Requests.

Creating an [issue][issues] prior to the Pull Request is highly recommended to
avoid multiple people working on the same issue, resulting in duplicated effort.

Visit the [Pull Requests][pulls] page.

## Releasing

To create new releases you'll need to have the following tools installed:

- [GoReleaser][goreleaser] >= 1.9
- [svu][svu] >= 1.9

[discussions]: https://github.com/orgs/reposaur/discussions
[issues]: https://github.com/reposaur/reposaur/issues
[pulls]: https://github.com/reposaur/reposaur/pulls
[bug-report]: https://github.com/reposaur/reposaur/issues/new?assignees=&labels=bug%2Ctriage&template=bug_report.yml&title=%5BBug%5D%3A+
[feature-request]: https://github.com/reposaur/reposaur/issues/new?assignees=&labels=enhancement%2Ctriage&template=feature_request.yml&title=%5BFeature%5D%3A+
[slack]: https://slack.reposaur.com
[go]: https://go.dev/
[task]: https://taskfile.dev/
[goreleaser]: https://goreleaser.com
[svu]: https://github.com/caarlos0/svu


================================================
FILE: LICENSE
================================================
MIT License

Copyright (c) 2022 João Cerqueira and Reposaur contributors

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

================================================
FILE: README.md
================================================
<div align="center">

[![logo][logo]][website]

# Reposaur

[![go-report][go-report-badge]][go-report]
[![tests-workflow][tests-workflow-badge]][tests-workflow]
[![license][license-badge]]()
[![discussions][discussions-badge]][discussions]
[![discord][discord-badge]][discord-invite]
[![twitter][twitter-badge]][twitter]

**Reposaur is the open source compliance tool for development platforms.**

Audit, verify and report on your data and configurations easily with pre-defined and/or custom policies. <br />
Supports GitHub. GitLab, BitBucket and Gitea support soon.
⚠️ before 1.0.0 expect some bugs and API changes ⚠️
[Getting started](#getting-started) •
[Installation](#installation) •
[Documentation][docs] •
[Guides](#guides) •
[Integrations](#integrations)

</div>

# Getting Started

Have you ever felt like you don't know what's happening in your GitHub/GitLab/BitBucket repositories? Between 100s or 1000s of them it's hard to make sure every single one is compliant to certain security and best practices guidelines.

Reposaur is here to fix that, empowering you to focus on your work instead of hunting for issues and misconfigurations.

## Features

- Custom policies using the [Rego][rego] policy language ([learn more][docs-policy])
- A simple, composable and easy-to-use CLI ([learn more][docs-cli])
- Extendable using a straightforward SDK (written in Go)
- Reports follow the standard SARIF format, enabling easy integrations with different systems
- Policies can be unit tested, guaranteeing they work as expected
- Integration with the major development platforms (see [Integrations](#integrations))
- Easily integrate new platforms using the SDK

## Guides

- [Writing your first policy](https://docs.reposaur.com/guides/writing-your-first-policy)

# Installation

#### Homebrew Tap

```shell
$ brew install reposaur/tap/reposaur
```

#### DEB, RPM and APK Packages

Download the `.deb`, `.rpm` or `.apk` packages from the [releases page][releases]
and install them with the appropriate tools.

#### Go

```shell
$ go install github.com/reposaur/reposaur/cmd/rsr@latest
```

#### Script

The script will download the latest release to a temporary directory and decompress
it to `$HOME/.reposaur`.

```shell
$ curl -sfL https://get.reposaur.com | bash
```

# Integrations

| Platform               | Status      | Details                                                                                   |
|------------------------|-------------|-------------------------------------------------------------------------------------------|
| [GitHub][github]       | In progress | [Provider][github-provider] • [GitHub App][github-app] • [GitHub Actions][github-actions] |
| [GitLab][gitlab]       | Planned     | N/A                                                                                       |
| [Gitea][gitea]         | Planned     | N/A                                                                                       |
| [BitBucket][bitbucket] | Not planned | N/A                                                                                       |

# Contributing

We appreciate every contribution, thanks for considering it!

**TLDR;**

- [Open an issue][issues] if you have a problem or found a bug
- [Open a Pull Request][pulls] if you have a suggestion, improvement or bug fix
- [Open a Discussion][discussions] if you have questions or want to discuss ideas

Check our [Contributing Guide](CONTRIBUTING.md) for more detailed information.

# License

This project is released under the [MIT License](LICENSE).

[website]: https://reposaur.com
[docs]: https://docs.reposaur.com
[docs-policy]: https://docs.reposaur.com/policy
[docs-cli]: https://docs.reposaur.com/cli/exec
[issues]: https://github.com/reposaur/reposaur/issues
[pulls]: https://github.com/reposaur/reposaur/pulls
[logo]: https://user-images.githubusercontent.com/8532541/169531963-bafd3cbf-dadd-486d-83cc-10a4d39c1dbc.png
[rego]: https://www.openpolicyagent.org/docs/latest/policy-language/
[license]: https://github.com/reposaur/reposaur/blob/main/LICENSE
[license-badge]: https://img.shields.io/github/license/reposaur/reposaur?style=flat-square&color=blueviolet
[go-report]: https://goreportcard.com/report/github.com/reposaur/reposaur
[go-report-badge]: https://goreportcard.com/badge/github.com/reposaur/reposaur?style=flat-square&color=blueviolet
[tests-workflow]: https://github.com/reposaur/reposaur/actions/workflows/test.yml
[tests-workflow-badge]: https://img.shields.io/github/workflow/status/reposaur/reposaur/Test?label=tests&style=flat-square
[discussions]: https://github.com/orgs/reposaur/discussions
[discussions-badge]: https://img.shields.io/github/discussions/reposaur/reposaur?style=flat-square&color=blueviolet
[discord-invite]: https://discord.gg/jpx4sqkQYY
[discord-badge]: https://img.shields.io/discord/1021712577132240898?label=discord&style=flat-square&color=blueviolet
[twitter]: https://twitter.com/reposaurhq
[twitter-badge]: https://img.shields.io/badge/twitter-%40reposaurhq-blueviolet?style=flat-square
[github]: https://github.com
[github-app]: https://docs.reposaur.com/integrations/github-app
[github-actions]: https://docs.reposaur.com/integrations/github-actions/setup-reposaur
[github-provider]: https://docs.reposaur.com/
[gitlab]: https://gitlab.com
[gitea]: https://gitea.io
[bitbucket]: https://bitbucket.org
[releases]: https://github.com/reposaur/reposaur/releases/latest


================================================
FILE: Taskfile.yaml
================================================
# https://taskfile.dev

version: "3"

tasks:
  deps:
    run: once
    cmds:
      - go mod tidy
    silent: true

  build:
    deps: [deps]
    vars:
      VERSION: devel
    cmds:
      - go build -ldflags "-s -w -X github.com/reposaur/reposaur/internal/build.Version={{.VERSION}}" -o ./bin/rsr ./cmd/rsr/rsr.go
    silent: true

  release:
    vars:
      VERSION:
        sh: "[ '{{.VERSION}}' != '' ] && echo '{{.VERSION}}' || svu"
    cmds:
      - git checkout main
      - git tag {{.VERSION}}
      - git push --tags
      - goreleaser --rm-dist
      - defer: rm -rf dist
    silent: true

  unreleased:
    desc: Prints the commits between main branch and latest version
    vars:
      VERSION:
        sh: "[ '{{.VERSION}}' != '' ] && echo '{{.VERSION}}' || curl -s https://api.github.com/repos/reposaur/reposaur/releases/latest | jq -r '.tag_name'"
    cmds:
      - git log --graph --pretty=format:'%Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr) %C(bold blue)<%an>%Creset' --abbrev-commit main...{{.VERSION}}
    silent: true


================================================
FILE: action.yml
================================================
name: Reposaur
author: Reposaur Authors
description: Audit your GitHub data using custom policies written in Rego

branding:
  icon: lock
  color: purple

inputs:
  version:
    description: Version
    default: main
    required: false

runs:
  using: composite
  steps:
    - run: |
        curl -o- https://raw.githubusercontent.com/reposaur/reposaur/${{ inputs.version }}/install.sh | bash
        echo "${{ github.action_path }}" >> $GITHUB_PATH
      working-directory: ${{ github.action_path }}
      shell: bash


================================================
FILE: cmd/rsr/internal/bundle/bundle.go
================================================
package bundle

import (
	"os"

	"github.com/reposaur/reposaur/cmd/rsr/internal/cmdutil"
	"github.com/reposaur/reposaur/pkg/sdk"
	"github.com/rs/zerolog"
	"github.com/spf13/cobra"
)

type bundleParams struct {
	policyPaths    []string
	experimental bool
}

func NewCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "bundle [-p POLICY_PATH...] <OUTPUT>",
		Short: "Creates a bundle from the policies at POLICY_PATH (experimental)",
		Long:  "Creates a bundle from the policies at POLICY_PATH (experimental)",
	}

	var (
		params = &bundleParams{}
		flags  = cmd.Flags()
	)

	cmdutil.AddPolicyPathsFlag(flags, &params.policyPaths)
	cmdutil.AddExperimentalFlag(flags, &params.experimental)

	cmd.Run = func(cmd *cobra.Command, args []string) {
		var (
			ctx    = cmd.Context()
			logger = zerolog.Ctx(ctx)
		)

		if !params.experimental {
			logger.Fatal().Msg("experimental feature, please use --experimental to accept")
		}

		if len(args) != 1 {
			logger.Fatal().Msgf("exactly 1 arguments required, got %d", len(args))
		}

		rsr, err := sdk.New(ctx, params.policyPaths, sdk.WithLogger(*logger))
		if err != nil {
			logger.Fatal().Err(err).Msg("could not instantiate SDK")
		}

		out, err := os.OpenFile(args[0], os.O_WRONLY+os.O_CREATE+os.O_TRUNC, 0o666)
		if err != nil {
			logger.Fatal().Err(err).Msg("could not open file")
		}

		err = rsr.Bundle(ctx, params.policyPaths, out)
		if err != nil {
			logger.Fatal().Err(err).Msg("could not create bundle")
		}

		logger.Info().Msgf("bundle written to %s", args[0])
	}

	return cmd
}


================================================
FILE: cmd/rsr/internal/cmdutil/env.go
================================================
package cmdutil

import (
	"fmt"
	"os"
	"strconv"
)

// getEnv looks up every key in keys in the environment variables and returns
// the first value found. If no value is found, returns an empty string.
func getEnv(keys ...string) string {
	for _, k := range keys {
		if v := os.Getenv(k); v != "" {
			return v
		}
	}

	return ""
}

// getInt64Env is similar to getEnv but converts the value to an int64. If no
// value is found returns the zero-value for int64.
func getInt64Env(keys ...string) int64 {
	val := getEnv(keys...)

	if val == "" {
		return 0
	}

	intVal, err := strconv.ParseInt(val, 10, 0)
	if err != nil {
		panic(fmt.Errorf("failed parsing env variable to int64: %w", err))
	}

	return intVal
}


================================================
FILE: cmd/rsr/internal/cmdutil/flag.go
================================================
package cmdutil

import (
	githubclient "github.com/reposaur/reposaur/provider/github/client"
	"github.com/spf13/pflag"
)

type GitHubClientOptions struct {
	// GitHub API Base URL
	BaseURL string

	// GitHub Personal Access Token
	Token string

	// GitHub App ID
	AppID int64

	// GitHub App Private Key
	AppPrivateKey string

	// GitHub App Installation ID
	InstallationID int64
}

func AddPolicyPathsFlag(flags *pflag.FlagSet, p *[]string) {
	flags.StringSliceVarP(p, "policy", "p", []string{"."}, "path to policy files or directories")
}

func AddOutputFlag(flags *pflag.FlagSet, p *string) {
	flags.StringVarP(p, "output", "o", "-", "output filename")
}

func AddTraceFlag(flags *pflag.FlagSet, p *bool) {
	flags.BoolVarP(p, "trace", "t", false, "enable tracing")
}

func AddVerboseFlag(flags *pflag.FlagSet, p *bool) {
	flags.BoolVarP(p, "verbose", "v", false, "print debug logs")
}

func AddExperimentalFlag(flags *pflag.FlagSet, p *bool) {
	flags.BoolVar(p, "experimental", false, "accepts the usage of experimental features")
}

func AddGitHubFlags(flags *pflag.FlagSet, p *GitHubClientOptions) {
	var (
		defURL            = getEnv("GH_API_URL", "GITHUB_API_URL")
		defToken          = getEnv("GH_TOKEN", "GITHUB_TOKEN")
		defAppID          = getInt64Env("GH_APP_ID", "GITHUB_APP_ID")
		defAppPrivKey     = getEnv("GH_APP_PRIVATE_KEY", "GITHUB_APP_PRIVATE_KEY")
		defInstallationID = getInt64Env("GH_INSTALLATION_ID", "GITHUB_INSTALLATION_ID")
	)

	if defURL == "" {
		defURL = githubclient.DefaultBaseURL
	}

	flags.StringVar(&p.BaseURL, "github-api-url", defURL, "base url GitHub API")
	flags.StringVar(&p.Token, "github-token", defToken, "token for GitHub")
	flags.Int64Var(&p.AppID, "github-app-id", defAppID, "id for GitHub App")
	flags.StringVar(&p.AppPrivateKey, "github-app-private-key", defAppPrivKey, "base64-encoded private key for GitHub App")
	flags.Int64Var(&p.InstallationID, "github-installation-id", defInstallationID, "installation ID for GitHub App")
}


================================================
FILE: cmd/rsr/internal/cmdutil/io.go
================================================
package cmdutil

import (
	"context"
	"io"
	"os"

	"github.com/rs/zerolog"
)

// GetInputReader returns an io.ReadCloser. If filename
// is not empty, the file is opened and returned. Otherwise,
// returns a reader from standard input.
func GetInputReader(ctx context.Context, filename string) (r io.ReadCloser, err error) {
	var (
		logger = zerolog.Ctx(ctx)
		file   = os.Stdin
	)

	if filename == "" || filename == "-" {
		logger.Debug().Msg("using standard input as INPUT")
	} else {
		logger.Debug().Msgf("using %s as INPUT", filename)

		file, err = os.Open(filename)
		if err != nil {
			return nil, err
		}
	}

	return file, nil
}

// GetOutputWriter returns an io.WriteCloser. If filename
// is not empty, the file is opened and returned. Otherwise,
// returns a writer to standard output.
func GetOutputWriter(ctx context.Context, filename string) (w io.WriteCloser, err error) {
	var (
		logger = zerolog.Ctx(ctx)
		file   = os.Stdout
	)

	if filename == "" || filename == "-" {
		logger.Debug().Msg("using standard output as OUTPUT")
	} else {
		logger.Debug().Msgf("using %s as OUTPUT", filename)

		file, err = os.OpenFile(filename, os.O_WRONLY+os.O_CREATE+os.O_TRUNC, 0o666)
		if err != nil {
			return nil, err
		}
	}

	return file, nil
}


================================================
FILE: cmd/rsr/internal/cmdutil/logger.go
================================================
package cmdutil

import (
	"os"

	"github.com/rs/zerolog"
)

// NewLogger returns a new logger that outputs to
// the standard error output. If verbose is true,
// the log level will be `debug`, otherwise will be info.
func NewLogger(verbose bool) zerolog.Logger {
	var (
		lvl = zerolog.InfoLevel
		cw  = zerolog.ConsoleWriter{Out: os.Stderr}
	)

	if verbose {
		lvl = zerolog.DebugLevel
	}

	return zerolog.New(cw).Level(lvl).With().Timestamp().Logger()
}


================================================
FILE: cmd/rsr/internal/exec/exec.go
================================================
package exec

import (
	"context"
	"encoding/json"
	"errors"
	"io"
	"os"
	"sync"
	"time"

	"github.com/reposaur/reposaur/cmd/rsr/internal/cmdutil"
	"github.com/reposaur/reposaur/pkg/output"
	"github.com/reposaur/reposaur/pkg/sdk"
	"github.com/reposaur/reposaur/provider/github"
	githubclient "github.com/reposaur/reposaur/provider/github/client"
	"github.com/rs/zerolog"
	"github.com/spf13/cobra"
)

type execParams struct {
	policyPaths    []string
	outputFilename string
	inputFilename  string
	enableTracing  bool
	github         cmdutil.GitHubClientOptions
}

func NewCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "exec [-p POLICY_PATH...] [-n NAMESPACE] [-o OUTPUT] INPUT",
		Short: "Executes policies against INPUT data",
		Long:  "Executes policies against INPUT data",
	}

	var (
		params = &execParams{}
		flags  = cmd.Flags()
	)

	cmdutil.AddOutputFlag(flags, &params.outputFilename)
	cmdutil.AddPolicyPathsFlag(flags, &params.policyPaths)
	cmdutil.AddTraceFlag(flags, &params.enableTracing)
	cmdutil.AddGitHubFlags(flags, &params.github)

	cmd.Run = func(cmd *cobra.Command, args []string) {
		var (
			ctx    = cmd.Context()
			logger = zerolog.Ctx(ctx)
		)

		if len(args) > 1 {
			logger.Fatal().Strs("args", args).Msg("too many arguments for INPUT")
		}

		if len(args) == 1 {
			params.inputFilename = args[0]
		}

		inReader, err := cmdutil.GetInputReader(ctx, params.inputFilename)
		if err != nil {
			logger.Fatal().Err(err).Msg("failed to get input reader")
		}
		defer func() {
			if err := inReader.Close(); err != nil {
				logger.Fatal().Err(err).Msg("failed to close input reader")
			}
		}()

		outWriter, err := cmdutil.GetOutputWriter(ctx, params.outputFilename)
		if err != nil {
			logger.Fatal().Err(err).Msg("failed to get output writer")
		}
		defer func() {
			if err := outWriter.Close(); err != nil {
				logger.Fatal().Err(err).Msg("failed to close output reader")
			}
		}()

		githubProvider, err := newGitHubProvider(ctx, &params.github)
		if err != nil {
			logger.Fatal().Err(err).Msg("failed to create GitHub provider")
		}

		opts := []sdk.Option{
			sdk.WithLogger(*logger),
			sdk.WithProvider(githubProvider),
			sdk.WithTracingEnabled(params.enableTracing),
		}

		rsr, err := sdk.New(ctx, params.policyPaths, opts...)
		if err != nil {
			logger.Fatal().Err(err).Msg("could not instantiate SDK")
		}

		runExec(ctx, rsr, inReader, outWriter)
	}

	return cmd
}

// runExec will execute the policies against the data available
// in inReader. The resulting reports will be outputted to outWriter.
func runExec(ctx context.Context, rsr *sdk.Reposaur, inReader io.ReadCloser, outWriter io.WriteCloser) {
	startTime := time.Now()

	var (
		inputsCh = make(chan interface{})
		inputsWg = sync.WaitGroup{}

		reportsCh = make(chan output.Report)
		reportsWg = sync.WaitGroup{}

		logger = zerolog.Ctx(ctx)
	)

	// Process inputs
	go func() {
		for input := range inputsCh {
			inputsWg.Done()
			reportsWg.Add(1)

			go func(input interface{}) {
				logger.Debug().Msg("processing input")

				report, err := rsr.Check(ctx, input)
				if err != nil {
					logger.Fatal().Err(err).Send()
				}

				logger.Debug().Msg("done processing input")

				reportsCh <- report
			}(input)
		}
	}()

	// Output reports
	go func() {
		enc := json.NewEncoder(outWriter)
		enc.SetIndent("", "  ")

		for report := range reportsCh {
			sarif, err := output.NewSarifReport(report)
			if err != nil {
				logger.Fatal().Err(err).Send()
			}

			if err := enc.Encode(sarif); err != nil {
				logger.Fatal().Err(err).Send()
			}

			reportsWg.Done()
		}
	}()

	// Start processing inputs
	dec := json.NewDecoder(inReader)

	for {
		var input interface{}

		if err := dec.Decode(&input); errors.Is(err, io.EOF) {
			break
		} else if err != nil {
			logger.Fatal().Err(err).Msg("failed to decode input")
		}

		switch inputT := input.(type) {
		case map[string]interface{}:
			logger.Debug().Msg("received 1 input")

			inputsWg.Add(1)
			inputsCh <- inputT

		case []interface{}:
			logger.Debug().Msgf("received %d inputs", len(inputT))

			for _, input := range inputT {
				inputsWg.Add(1)
				inputsCh <- input
			}
		}
	}

	inputsWg.Wait()
	close(inputsCh)
	logger.Debug().Msg("closed inputs channel")

	reportsWg.Wait()
	close(reportsCh)
	logger.Debug().Msg("closed reports channel")

	logger.Info().Dur("timeElapsed", time.Since(startTime)).Msg("done")

	// TODO: should exit with 1 if there are failed results
	os.Exit(0)
}

func newGitHubProvider(ctx context.Context, opts *cmdutil.GitHubClientOptions) (*github.GitHub, error) {
	var client *githubclient.Client

	if opts.AppID != 0 && opts.InstallationID != 0 && opts.AppPrivateKey != "" {
		appClient, err := githubclient.NewAppClient(ctx, opts.BaseURL, opts.AppID, opts.InstallationID, []byte(opts.AppPrivateKey))
		if err != nil {
			return nil, err
		}

		client = appClient
	} else if opts.Token != "" {
		client = githubclient.NewTokenClient(ctx, opts.Token)
	}

	return github.NewProvider(client), nil
}


================================================
FILE: cmd/rsr/internal/root/root.go
================================================
package root

import (
	"github.com/reposaur/reposaur/cmd/rsr/internal/bundle"
	"github.com/reposaur/reposaur/cmd/rsr/internal/cmdutil"
	"github.com/reposaur/reposaur/cmd/rsr/internal/exec"
	"github.com/reposaur/reposaur/cmd/rsr/internal/test"
	"github.com/reposaur/reposaur/internal/build"
	"github.com/spf13/cobra"
)

type rootParams struct {
	verbose bool
}

func NewCmd() *cobra.Command {
	cmd := &cobra.Command{
		Version: build.Version,
		Use:     "rsr",
		Short:   "Reposaur - security & compliance for GitHub metadata",
	}

	params := &rootParams{}

	cmdutil.AddVerboseFlag(cmd.PersistentFlags(), &params.verbose)

	cmd.PersistentPreRun = func(cmd *cobra.Command, args []string) {
		logger := cmdutil.NewLogger(params.verbose)

		cmd.SetContext(
			logger.WithContext(cmd.Context()),
		)
	}

	cmd.AddCommand(
		exec.NewCmd(),
		test.NewCmd(),
		bundle.NewCmd(),
	)

	return cmd
}


================================================
FILE: cmd/rsr/internal/test/test.go
================================================
package test

import (
	"context"
	"os"
	"time"

	"github.com/reposaur/reposaur/cmd/rsr/internal/cmdutil"
	"github.com/reposaur/reposaur/pkg/sdk"
	"github.com/rs/zerolog"
	"github.com/spf13/cobra"
)

type testParams struct {
	policyPaths    []string
	outputFilename string
	enableTracing  bool
}

func NewCmd() *cobra.Command {
	cmd := &cobra.Command{
		Use:   "test POLICY_PATH...",
		Short: "Runs the tests available in POLICY_PATH",
		Long:  "Runs the tests available in POLICY_PATH",
	}

	var (
		params = &testParams{policyPaths: []string{"."}}
		flags  = cmd.Flags()
	)

	cmdutil.AddOutputFlag(flags, &params.outputFilename)
	cmdutil.AddTraceFlag(flags, &params.enableTracing)

	cmd.Run = func(cmd *cobra.Command, args []string) {
		var (
			ctx    = cmd.Context()
			logger = zerolog.Ctx(ctx)
		)

		opts := []sdk.Option{
			sdk.WithLogger(*logger),
			sdk.WithTracingEnabled(params.enableTracing),
		}

		if len(args) > 0 {
			params.policyPaths = args
		}

		rsr, err := sdk.New(ctx, params.policyPaths, opts...)
		if err != nil {
			logger.Fatal().Err(err).Msg("could not instantiate SDK")
		}

		runTest(ctx, rsr)
	}

	return cmd
}

// runTest executes policy tests, outputting the results
// to the provided  outWriter.
//
// If any test fails, the function will exit with code 1.
// Otherwise, exits with code 0.
func runTest(ctx context.Context, rsr *sdk.Reposaur) {
	var (
		startTime = time.Now()
		logger    = zerolog.Ctx(ctx)
	)

	results, err := rsr.Test(ctx)
	if err != nil {
		logger.Fatal().Err(err).Msg("failed to execute tests")
	}

	var failedTests, totalTests int

	for _, r := range results {
		totalTests++

		if r.Fail {
			failedTests++
			logger.Error().Msg(r.String())
		} else {
			logger.Info().Msg(r.String())
		}
	}

	testLogger := logger.With().
		Int("passed", totalTests-failedTests).
		Int("failed", failedTests).
		Int("total", totalTests).
		Dur("timeElapsed", time.Since(startTime)).
		Logger()

	if failedTests > 0 {
		testLogger.Error().Msg("done")
		os.Exit(1)
	}

	testLogger.Info().Msg("done")
	os.Exit(0)
}


================================================
FILE: cmd/rsr/rsr.go
================================================
package main

import (
	"fmt"
	"os"

	"github.com/reposaur/reposaur/cmd/rsr/internal/root"
)

func main() {
	if err := root.NewCmd().Execute(); err != nil {
		if _, err := fmt.Fprintln(os.Stderr, err); err != nil {
			panic(err)
		}
		os.Exit(1)
	}
}


================================================
FILE: go.mod
================================================
module github.com/reposaur/reposaur

go 1.18

require (
	github.com/bradleyfalzon/ghinstallation/v2 v2.1.0
	github.com/hashicorp/go-retryablehttp v0.7.2
	github.com/open-policy-agent/opa v0.48.0
	github.com/owenrumney/go-sarif/v2 v2.1.2
	github.com/rs/zerolog v1.28.0
	github.com/spf13/cobra v1.6.1
	github.com/spf13/pflag v1.0.5
	golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5
)

require (
	github.com/OneOfOne/xxhash v1.2.8 // indirect
	github.com/agnivade/levenshtein v1.1.1 // indirect
	github.com/ghodss/yaml v1.0.0 // indirect
	github.com/gobwas/glob v0.2.3 // indirect
	github.com/golang-jwt/jwt/v4 v4.4.1 // indirect
	github.com/golang/protobuf v1.5.2 // indirect
	github.com/google/go-github/v45 v45.2.0 // indirect
	github.com/google/go-querystring v1.1.0 // indirect
	github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
	github.com/inconshreveable/mousetrap v1.0.1 // indirect
	github.com/mattn/go-colorable v0.1.12 // indirect
	github.com/mattn/go-isatty v0.0.14 // indirect
	github.com/pkg/errors v0.9.1 // indirect
	github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 // indirect
	github.com/tchap/go-patricia/v2 v2.3.1 // indirect
	github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
	github.com/yashtewari/glob-intersection v0.1.0 // indirect
	golang.org/x/crypto v0.4.0 // indirect
	golang.org/x/net v0.5.0 // indirect
	golang.org/x/sys v0.4.0 // indirect
	google.golang.org/appengine v1.6.7 // indirect
	google.golang.org/protobuf v1.28.1 // indirect
	gopkg.in/yaml.v2 v2.4.0 // indirect
)


================================================
FILE: go.sum
================================================
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/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=
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.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8=
github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q=
github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8=
github.com/agnivade/levenshtein v1.1.1/go.mod h1:veldBMzWxcCG2ZvUTKD2kJNRdCk5hVbJomOvKkmgYbo=
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
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/bytecodealliance/wasmtime-go/v3 v3.0.2 h1:3uZCA/BLTIu+DqCfguByNMJa2HVHpXvjfy0Dy7g6fuA=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
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/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
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/dgraph-io/badger/v3 v3.2103.5 h1:ylPa6qzbjYRQMU6jokoj4wzcaweHylt//CH0AKt0akg=
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48 h1:fRzb/w+pyskVMQ+UbP35JkH8yB7MYb4q/qhBarqZE6g=
github.com/dgryski/trifles v0.0.0-20200323201526-dd97f9abfb48/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
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/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/foxcpp/go-mockdns v0.0.0-20210729171921-fb145fc6f897 h1:E52jfcE64UG42SwLmrW0QByONfGynWuzBvm86BoB9z8=
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
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/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
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/glog v1.0.0 h1:nfP3RFugxnNRyKgeWd4oI1nYvXpxrx8ck8ZrcizshdQ=
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/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.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/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
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/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw=
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.5/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-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-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/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/martian/v3 v3.0.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/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
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/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
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/inconshreveable/mousetrap v1.0.1 h1:U3uMjPSQEBMNp1lFxmllqCPM6P5u/Xq7Pgzkat/bFNc=
github.com/inconshreveable/mousetrap v1.0.1/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
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.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
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 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo=
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
github.com/open-policy-agent/opa v0.48.0 h1:s2K823yohAUu/HB4MOPWDhBh88JMKQv7uTr6S89fbM0=
github.com/open-policy-agent/opa v0.48.0/go.mod h1:CsQcksP+qGBxO9oEBj1NnZqKcjgjmTJbRNTzjZB/DXQ=
github.com/owenrumney/go-sarif v1.1.1/go.mod h1:dNDiPlF04ESR/6fHlPyq7gHKmrM0sHUvAGjsoh8ZH0U=
github.com/owenrumney/go-sarif/v2 v2.1.2 h1:PMDK7tXShJ9zsB7bfvlpADH5NEw1dfA9xwU8Xtdj73U=
github.com/owenrumney/go-sarif/v2 v2.1.2/go.mod h1:MSqMMx9WqlBSY7pXoOZWgEsVB4FDNfhcaXDA1j6Sr+w=
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=
github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4=
github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE=
github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0 h1:MkV+77GLUNo5oJ0jf870itWm3D0Sjh7+Za9gazKc5LQ=
github.com/rcrowley/go-metrics v0.0.0-20200313005456-10cdbea86bc0/go.mod h1:bCqnVzQkZxMG4s8nGwiZ5l3QUCyqpo9Y+/ZMZ9VjZe4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.28.0 h1:MirSo27VyNi7RJYP3078AA1+Cyzd2GB66qy3aUHvsWY=
github.com/rs/zerolog v1.28.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/spf13/cobra v1.6.1 h1:o94oiPyS4KD1mPy2fmcYYHHfCxLqYjJOhGsCHFZtEzA=
github.com/spf13/cobra v1.6.1/go.mod h1:IOw/AERYS7UzyrGinqmz6HLUo219MORXGxhbaJUqzrY=
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/stretchr/objx v0.1.0/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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.1 h1:w7B6lhMri9wdJUVmEZPGGhZzrYTPvgJArz7wNPgYKsk=
github.com/tchap/go-patricia/v2 v2.3.1 h1:6rQp39lgIYZ+MHmdEq4xzuk1t7OdC35z/xm0BGhTkes=
github.com/tchap/go-patricia/v2 v2.3.1/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo=
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
github.com/yashtewari/glob-intersection v0.1.0 h1:6gJvMYQlTDOL3dMsPF6J0+26vwX9MB8/1q3uAdhmTrg=
github.com/yashtewari/glob-intersection v0.1.0/go.mod h1:LK7pIC3piUjovexikBbJ26Yml7g8xa5bsjfx2v1fwok=
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/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
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.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M=
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.4.0 h1:UVQgzMY87xqpKNgb+kDsll2Igd33HszWHFLmpaRMq/8=
golang.org/x/crypto v0.4.0/go.mod h1:3quD/ATkf6oY+rnes5c3ExXTbLc8mueNue5/DoinL80=
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/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/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-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
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=
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-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE=
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/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/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-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-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
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-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/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/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.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
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/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/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-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/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/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.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=
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.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.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=


================================================
FILE: install.sh
================================================
#!/bin/sh
set -e

RELEASES_URL="https://github.com/reposaur/reposaur/releases"
FILE_BASENAME="reposaur"

test -z "$VERSION" && VERSION="$(curl -sfL -o /dev/null -w %{url_effective} "$RELEASES_URL/latest" |
  rev |
  cut -f1 -d'/' |
  rev)"

test -z "$VERSION" && {
  echo "Unable to get Reposaur version." >&2
  exit 1
}

test -z "$TEMP_DIR" && TEMP_DIR="$(mktemp -d)"
test -z "$INSTALLATION_DIR" && INSTALLATION_DIR="${HOME}/.reposaur"

mkdir -p "${INSTALLATION_DIR}/bin"

export TAR_FILE="$TEMP_DIR/${FILE_BASENAME}_$(uname -s)_$(uname -m).tar.gz"

echo "Downloading Reposaur ${VERSION}..."
curl -sfLo "$TAR_FILE" \
  "$RELEASES_URL/download/${VERSION}/${FILE_BASENAME}_${VERSION#v}_$(uname -s)_$(uname -m).tar.gz"

echo ""
echo "Installing Reposaur to ${INSTALLATION_DIR}..."
tar -xf "${TAR_FILE}" -C "${INSTALLATION_DIR}"
mv "${INSTALLATION_DIR}/rsr" "${INSTALLATION_DIR}/bin"

# This binary will be deprecated soon
mv "${INSTALLATION_DIR}/reposaur" "${INSTALLATION_DIR}/bin"

echo ""
echo "Done, try running:"
echo "\t${INSTALLATION_DIR}/bin/rsr --help"
echo ""
echo "It's recommended to add the bin directory to your PATH:"
echo "\tPATH=\"\$PATH:${INSTALLATION_DIR}/bin\""


================================================
FILE: internal/build/build.go
================================================
package build

import (
	"runtime/debug"
)

// Version is dynamically set by the toolchain.
var Version = "DEV"

func init() {
	if Version == "DEV" {
		if info, ok := debug.ReadBuildInfo(); ok && info.Main.Version != "(devel)" {
			Version = info.Main.Version
		}
	}
}


================================================
FILE: internal/policy/engine.go
================================================
package policy

import (
	"context"
	"fmt"
	"os"
	"strings"

	"github.com/open-policy-agent/opa/ast"
	"github.com/open-policy-agent/opa/bundle"
	"github.com/open-policy-agent/opa/loader"
	"github.com/open-policy-agent/opa/rego"
	"github.com/open-policy-agent/opa/topdown"
	"github.com/reposaur/reposaur/pkg/output"
)

type Option func(*Engine)

type Engine struct {
	modules       map[string]*ast.Module
	compiler      *ast.Compiler
	enableTracing bool
}

func Load(_ context.Context, policyPaths []string, opts ...Option) (*Engine, error) {
	policies, err := loader.NewFileLoader().
		WithProcessAnnotation(true).
		Filtered(policyPaths, isRegoFile)
	if err != nil {
		return nil, &ErrPolicyLoad{err}
	}

	if len(policies.Modules) == 0 {
		return nil, &ErrNoPolicies{policyPaths}
	}

	modules := policies.ParsedModules()
	compiler := ast.NewCompiler().WithEnablePrintStatements(true)

	compiler.Compile(modules)

	if compiler.Failed() {
		return nil, fmt.Errorf("compiler: %w", compiler.Errors)
	}

	engine := &Engine{
		modules:  modules,
		compiler: compiler,
	}

	for _, opt := range opts {
		opt(engine)
	}

	return engine, nil
}

// WithTracingEnabled enables or disables policy
// execution tracing.
func WithTracingEnabled(enabled bool) Option {
	return func(e *Engine) {
		e.enableTracing = enabled
	}
}

// Namespaces returns all the namespaces in the engine.
func (e *Engine) Namespaces() []string {
	var namespaces []string
	for _, module := range e.Modules() {
		namespace := strings.Replace(module.Package.Path.String(), "data.", "", 1)
		for _, ns := range namespaces {
			if ns == namespace {
				continue
			}
		}

		namespaces = append(namespaces, namespace)
	}

	return namespaces
}

// Compiler returns the compiler from the loaded policies.
func (e *Engine) Compiler() *ast.Compiler {
	return e.compiler
}

// Modules returns the modules from the loaded policies.
func (e *Engine) Modules() map[string]*ast.Module {
	return e.modules
}

func (e *Engine) Check(ctx context.Context, namespace string, input interface{}) (output.Report, error) {
	report, err := e.check(ctx, namespace, input)
	if err != nil {
		return output.Report{}, fmt.Errorf("check: %w", err)
	}

	return report, nil
}

func (e *Engine) check(ctx context.Context, namespace string, input interface{}) (output.Report, error) {
	report := output.Report{
		Rules:   map[string]*output.Rule{},
		Results: map[string]*output.Result{},
	}

	for _, mod := range e.Modules() {
		currNamespace := strings.TrimPrefix(mod.Package.Path.String(), "data.")
		if currNamespace != namespace {
			continue
		}

		for _, r := range mod.Rules {
			var annotations *ast.Annotations
			for _, a := range mod.Annotations {
				if a.Scope == "rule" && a.GetTargetPath().String() == r.Ref().String() {
					annotations = a
				}
			}

			rule, err := output.NewRule(namespace, r, annotations)
			if err != nil {
				continue
			}

			report.AddRule(rule)
		}
	}

	for _, rule := range report.Rules {
		var result *output.Result

		result, err := e.querySkip(ctx, rule, input)
		if err != nil {
			return output.Report{}, fmt.Errorf("query skip rule: %s: %w", rule.UID(), err)
		}

		if !result.Skipped {
			result, err = e.queryRule(ctx, rule, input)
			if err != nil {
				return output.Report{}, fmt.Errorf("query rule: %s: %w", rule.UID(), err)
			}
		}

		report.AddResult(result)
	}

	return report, nil
}

func (e *Engine) queryRule(ctx context.Context, rule *output.Rule, input interface{}) (*output.Result, error) {
	query := fmt.Sprintf("data.%s.%s_%s", rule.Namespace, rule.Kind, rule.ID)
	regoInstance := e.buildRegoInstance(query, input)

	resultSet, err := regoInstance.Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("query eval: %w", err)
	}

	result := output.Result{
		Rule:   rule,
		Query:  query,
		Passed: len(resultSet) == 0,
	}

	return &result, nil
}

func (e *Engine) querySkip(ctx context.Context, rule *output.Rule, input interface{}) (*output.Result, error) {
	query := fmt.Sprintf("data.%s.skip[_][_] == %q", rule.Namespace, rule.ID)
	regoInstance := e.buildRegoInstance(query, input)

	resultSet, err := regoInstance.Eval(ctx)
	if err != nil {
		return nil, fmt.Errorf("skip query eval: %w", err)
	}

	result := output.Result{
		Rule:    rule,
		Query:   query,
		Skipped: len(resultSet) > 0,
	}

	return &result, nil
}

func (e *Engine) buildRegoInstance(query string, input interface{}) *rego.Rego {
	return rego.New(
		rego.Query(query),
		rego.Input(input),
		rego.Compiler(e.compiler),
		rego.Trace(e.enableTracing),
		rego.StrictBuiltinErrors(true),
		rego.PrintHook(topdown.NewPrintHook(os.Stderr)),
	)
}

func isRegoFile(_ string, info os.FileInfo, _ int) bool {
	return !info.IsDir() && !strings.HasSuffix(info.Name(), bundle.RegoExt)
}


================================================
FILE: internal/policy/errors.go
================================================
package policy

import "fmt"

type ErrPolicyLoad struct {
	loaderError error
}

func (e *ErrPolicyLoad) Error() string {
	return fmt.Sprintf("load: %v", e.loaderError)
}

type ErrNoPolicies struct {
	policyPaths []string
}

func (e *ErrNoPolicies) Error() string {
	return fmt.Sprintf("no policy .rego files found in %v", e.policyPaths)
}


================================================
FILE: pkg/output/report.go
================================================
package output

import (
	"fmt"
	"strings"

	"github.com/open-policy-agent/opa/ast"
)

type Severity string

const (
	ErrorSeverity   = "error"
	WarningSeverity = "warning"
	NoteSeverity    = "note"
)

var SeverityRuleMap = map[string][]string{
	ErrorSeverity:   {"error", "fail", "violation"},
	WarningSeverity: {"warn"},
	NoteSeverity:    {"note", "info"},
}

var SecuritySeverityMap = map[string]string{
	ErrorSeverity:   "7",
	WarningSeverity: "4",
	NoteSeverity:    "1",
}

type Report struct {
	Rules      map[string]*Rule   `json:"rules"`
	Results    map[string]*Result `json:"results"`
	RuleCount  int                `json:"ruleCount"`
	Properties ReportProperties   `json:"properties"`
}

func (r *Report) AddRule(rule *Rule) {
	r.RuleCount++
	r.Rules[rule.UID()] = rule
}

func (r *Report) AddResult(result *Result) {
	r.Results[result.Rule.UID()] = result
}

type ReportProperties map[string]interface{}

type Result struct {
	Rule    *Rule  `json:"rule"`
	Query   string `json:"query"`
	Skipped bool   `json:"skipped"`
	Passed  bool   `json:"passed"`
}

type Rule struct {
	ID               string   `json:"id"`
	Title            string   `json:"title"`
	Kind             string   `json:"kind"`
	Severity         string   `json:"severity"`
	SecuritySeverity string   `json:"security-severity"`
	Description      string   `json:"description"`
	Namespace        string   `json:"namespace"`
	Tags             []string `json:"tags"`
}

func NewRule(namespace string, rule *ast.Rule, as *ast.Annotations) (*Rule, error) {
	headSplit := strings.SplitN(rule.Head.Name.String(), "_", 2)

	if len(headSplit) != 2 {
		return nil, fmt.Errorf("new rule: parse id: invalid rule name: %s", rule.Head.Name.String())
	}

	var (
		kind     = headSplit[0]
		id       = headSplit[1]
		severity = ""
	)

	for sev, kinds := range SeverityRuleMap {
		for _, k := range kinds {
			if k == kind {
				severity = sev
				break
			}
		}

		if severity != "" {
			break
		}
	}

	if severity == "" {
		return nil, fmt.Errorf("new rule: could not find severity for %s", kind)
	}

	r := Rule{
		ID:               id,
		Title:            id,
		Kind:             kind,
		Severity:         severity,
		SecuritySeverity: SecuritySeverityMap[severity],
		Namespace:        namespace,
	}

	if as != nil {
		if as.Title != "" {
			r.Title = as.Title
		} else {
			r.Title = r.ID
		}

		if as.Description != "" {
			r.Description = as.Description
		} else {
			r.Description = r.Title
		}

		if tags, ok := as.Custom["tags"]; ok {
			for _, t := range tags.([]interface{}) {
				r.Tags = append(r.Tags, t.(string))
			}
		}

		if secSev, ok := as.Custom["security-severity"]; ok {
			r.SecuritySeverity = fmt.Sprintf("%v", secSev)
		}
	}

	return &r, nil
}

func (r Rule) CausesFailure() bool {
	return r.Severity == ErrorSeverity
}

func (r Rule) UID() string {
	return fmt.Sprintf("%s/%s/%s", r.Namespace, r.Kind, r.ID)
}


================================================
FILE: pkg/output/sarif.go
================================================
package output

import (
	"strings"

	"github.com/owenrumney/go-sarif/v2/sarif"
)

func NewSarifReport(report Report) (*sarif.Report, error) {
	sr, err := sarif.New(sarif.Version210)
	if err != nil {
		return nil, err
	}

	run := sarif.NewRunWithInformationURI("Reposaur", "https://github.com/reposaur/reposaur")

	run.Properties = sarif.Properties{}
	for k, v := range report.Properties {
		run.Properties[k] = v
	}

	for _, rule := range report.Rules {
		props := sarif.Properties{}

		if len(rule.Tags) > 0 {
			props["tags"] = rule.Tags
		}

		if rule.SecuritySeverity != "" {
			props["security-severity"] = rule.SecuritySeverity
		}

		run.AddRule(rule.UID()).
			WithName(rule.Title).
			WithDescription(rule.Title).
			WithFullDescription(
				sarif.NewMultiformatMessageString(rule.Description).
					WithMarkdown(rule.Description),
			).
			WithMarkdownHelp(rule.Description).
			WithProperties(props)
	}

	for _, result := range report.Results {
		if !result.Passed && !result.Skipped {
			run.AddResult(sarif.NewRuleResult(result.Rule.UID()).
				WithLevel(strings.ToLower(result.Rule.Severity)).
				WithMessage(sarif.NewTextMessage(result.Rule.Title)).
				WithLocations([]*sarif.Location{
					sarif.NewLocation().WithPhysicalLocation(
						sarif.NewPhysicalLocation().
							WithArtifactLocation(
								sarif.NewSimpleArtifactLocation("."),
							),
					),
				}),
			)
		}
	}

	sr.AddRun(run)

	return sr, nil
}


================================================
FILE: pkg/sdk/sdk.go
================================================
package sdk

import (
	"bytes"
	"context"
	"errors"
	"fmt"
	"io"
	"os"
	"strings"

	"github.com/open-policy-agent/opa/compile"
	"github.com/open-policy-agent/opa/rego"
	"github.com/open-policy-agent/opa/tester"
	"github.com/open-policy-agent/opa/topdown"
	"github.com/reposaur/reposaur/internal/policy"
	"github.com/reposaur/reposaur/pkg/output"
	"github.com/reposaur/reposaur/provider"
	"github.com/reposaur/reposaur/provider/github"

	"github.com/rs/zerolog"
)

var DefaultProviders = []provider.Provider{
	github.NewProvider(nil),
}

// Option represents a Reposaur option that can change a
// particular behavior.
type Option func(*Reposaur)

// Reposaur represents an instance of the auditing engine. It can be
// started with several options that control configuration, logging and
// the client to GitHub.
type Reposaur struct {
	logger        zerolog.Logger
	engine        *policy.Engine
	providers     []provider.Provider
	enableTracing bool
}

// New returns a new Reposaur instance, loading and
// compiling any policies provided and registering
// the built-in functions.
//
// If an HTTP client isn't passed as an option, a default
// client is created. A default (unauthenticated) client is created
// using `util.GitHubTransport`.
//
// The util functions available in the `util` package can be used to
// create authenticated HTTP clients.
//
// The default HTTP client will use the default host `api.github.com`. Can
// be customized using the `GITHUB_HOST` or `GH_HOST` environment variables.
func New(ctx context.Context, policyPaths []string, opts ...Option) (*Reposaur, error) {
	sdk := &Reposaur{
		logger: zerolog.New(os.Stderr),
	}

	for _, opt := range opts {
		opt(sdk)
	}

	if len(sdk.providers) == 0 {
		sdk.providers = DefaultProviders
	}

	for _, p := range sdk.providers {
		for _, b := range p.Builtins() {
			rego.RegisterBuiltinDyn(b.Func(), b.Impl)
		}
	}

	var err error
	sdk.engine, err = policy.Load(ctx, policyPaths, policy.WithTracingEnabled(sdk.enableTracing))
	if err != nil {
		return nil, err
	}

	return sdk, nil
}

// WithProvider adds a provider to Reposaur.
func WithProvider(provider provider.Provider) Option {
	return func(sdk *Reposaur) {
		sdk.providers = append(sdk.providers, provider)
	}
}

// WithLogger sets the logger used by Reposaur.
func WithLogger(logger zerolog.Logger) Option {
	return func(sdk *Reposaur) {
		sdk.logger = logger
	}
}

// WithTracingEnabled enables or disables policy
// execution tracing.
func WithTracingEnabled(enabled bool) Option {
	return func(sdk *Reposaur) {
		sdk.enableTracing = enabled
	}
}

// Logger returns Reposaur logger.
func (sdk Reposaur) Logger() zerolog.Logger {
	return sdk.logger
}

// Engine returns Reposaur policy engine.
func (sdk Reposaur) Engine() *policy.Engine {
	return sdk.engine
}

// Check executes the policies loaded against data. Data is checked against every
// provider to derive a namespace and additional report properties.
func (sdk Reposaur) Check(ctx context.Context, data interface{}) (output.Report, error) {
	var (
		dataProvider provider.Provider
		namespace    provider.Namespace
		err          error
	)

	for _, p := range sdk.providers {
		namespace, err = provider.DeriveNamespace(p, data)
		if err != nil {
			if errors.Is(err, provider.ErrNonDerivable) {
				continue
			}

			return output.Report{}, err
		}

		dataProvider = p
	}

	if dataProvider == nil {
		return output.Report{}, errors.New("could not derive a valid namespace from data")
	}

	report, err := sdk.engine.Check(ctx, string(namespace), data)
	if err != nil {
		return output.Report{}, err
	}

	report.Properties, err = provider.DeriveProperties(dataProvider, namespace, data)
	if err != nil && !errors.Is(err, provider.ErrNonDerivable) {
		return output.Report{}, err
	}

	return report, nil
}

func (sdk Reposaur) Test(ctx context.Context) ([]*tester.Result, error) {
	runner := tester.NewRunner().
		EnableTracing(sdk.enableTracing).
		CapturePrintOutput(true).
		SetCompiler(sdk.engine.Compiler()).
		SetModules(sdk.engine.Modules())

	ch, err := runner.RunTests(ctx, nil)
	if err != nil {
		return nil, fmt.Errorf("running tests: %w", err)
	}

	var rawResults []*tester.Result
	for result := range ch {
		if result.Error != nil {
			return nil, fmt.Errorf("run test: %w", result.Error)
		}

		rawResults = append(rawResults, result)
		buf := new(bytes.Buffer)
		topdown.PrettyTrace(buf, result.Trace)

		var traces []string
		for _, line := range strings.Split(buf.String(), "\n") {
			if len(line) > 0 {
				traces = append(traces, line)
			}
		}

		for _, t := range traces {
			if _, err := fmt.Fprintln(os.Stderr, t); err != nil {
				return nil, err
			}
		}
	}

	return rawResults, nil
}

// Bundle builds a new OCI-compatible policy bundle.
func (sdk Reposaur) Bundle(ctx context.Context, paths []string, out io.Writer) error {
	c := compile.New().
		WithOutput(out).
		WithTarget("rego").
		WithPaths(paths...)

	if err := c.Build(ctx); err != nil {
		return err
	}

	return nil
}


================================================
FILE: provider/github/client/client.go
================================================
package client

import (
	"context"
	"net/http"
	"net/url"

	"github.com/bradleyfalzon/ghinstallation/v2"
	"github.com/hashicorp/go-retryablehttp"
	"golang.org/x/oauth2"
)

const (
	DefaultBaseURL = "https://api.github.com"
)

type Client struct {
	BaseURL *url.URL

	client       *retryablehttp.Client
	appTransport *ghinstallation.Transport
	token        string
}

func NewClient(httpClient *http.Client) *Client {
	baseURL, _ := url.Parse(DefaultBaseURL)
	client := newRetryableClient(httpClient)

	return &Client{
		BaseURL: baseURL,
		client:  client,
	}
}

func NewTokenClient(ctx context.Context, token string) *Client {
	tokenSrc := oauth2.StaticTokenSource(&oauth2.Token{
		AccessToken: token,
	})

	oauthClient := oauth2.NewClient(ctx, tokenSrc)

	client := NewClient(oauthClient)
	client.token = token

	return client
}

func NewAppClient(_ context.Context, baseURL string, appID, installationID int64, privateKey []byte) (*Client, error) {
	appTransport, err := ghinstallation.New(http.DefaultTransport, appID, installationID, privateKey)
	if err != nil {
		return nil, err
	}

	appTransport.BaseURL = baseURL

	httpClient := &http.Client{
		Transport: appTransport,
	}

	client := NewClient(httpClient)
	client.appTransport = appTransport

	return client, nil
}

func (c Client) Client() *http.Client {
	return c.client.HTTPClient
}

func (c Client) Token(ctx context.Context) (string, error) {
	if c.appTransport != nil {
		return c.appTransport.Token(ctx)
	}

	return c.token, nil
}

func (c Client) NewRequest(method, path string, rawBody any) (*retryablehttp.Request, error) {
	u, err := c.BaseURL.Parse(path)
	if err != nil {
		return nil, err
	}

	req, err := retryablehttp.NewRequest(method, u.String(), rawBody)
	if err != nil {
		return nil, err
	}

	if rawBody != nil {
		req.Header.Set("Content-Type", "application/json")
	}

	req.Header.Set("User-Agent", "reposaur")

	return req, nil
}

func (c Client) Do(req *retryablehttp.Request) (*http.Response, error) {
	return c.client.Do(req)
}

func newRetryableClient(httpClient *http.Client) *retryablehttp.Client {
	client := retryablehttp.NewClient()

	if httpClient != nil {
		client.HTTPClient = httpClient
	}

	return client
}


================================================
FILE: provider/github/github.go
================================================
package github

import (
	"github.com/reposaur/reposaur/provider"
	"github.com/reposaur/reposaur/provider/github/client"
	"github.com/reposaur/reposaur/provider/github/internal/builtin"
)

const (
	IssueNamespace        provider.Namespace = "github.issue"
	OrganizationNamespace provider.Namespace = "github.organization"
	PullRequestNamespace  provider.Namespace = "github.pull_request"
	RepositoryNamespace   provider.Namespace = "github.repository"
	UserNamespace         provider.Namespace = "github.user"
)

type GitHub struct {
	client      *client.Client
	dataDeriver *DataDeriver
	builtins    []provider.Builtin
}

func NewProvider(c *client.Client) *GitHub {
	if c == nil {
		c = client.NewClient(nil)
	}

	return &GitHub{
		client: c,
		builtins: []provider.Builtin{
			&builtin.GraphQL{Client: c},
			&builtin.Request{Client: c},
		},
		dataDeriver: &DataDeriver{
			namespaceToKeys: map[provider.Namespace][]string{
				IssueNamespace:        {"reactions", "closed_by"},
				OrganizationNamespace: {"login", "members_url"},
				PullRequestNamespace:  {"base", "head"},
				RepositoryNamespace:   {"owner", "full_name"},
				UserNamespace:         {"login", "hireable"},
			},
		},
	}
}

func (gh GitHub) DeriveNamespace(data map[string]any) (provider.Namespace, error) {
	return gh.dataDeriver.DeriveNamespace(data)
}

func (gh GitHub) DeriveProperties(namespace provider.Namespace, data map[string]any) (map[string]any, error) {
	return gh.dataDeriver.DeriveProperties(namespace, data)
}

func (gh GitHub) Builtins() []provider.Builtin {
	return gh.builtins
}

type DataDeriver struct {
	namespaceToKeys map[provider.Namespace][]string
}

func (d DataDeriver) DeriveNamespace(data map[string]any) (provider.Namespace, error) {
	for namespace, keys := range d.namespaceToKeys {
		var matches int

		for _, key := range keys {
			for dataKey := range data {
				if key == dataKey {
					matches++
				}
			}

			if matches == len(keys) {
				return namespace, nil
			}
		}
	}

	return "", provider.ErrNonDerivable
}

func (d DataDeriver) DeriveProperties(namespace provider.Namespace, data map[string]any) (map[string]any, error) {
	switch namespace {
	case IssueNamespace, PullRequestNamespace:
		props := map[string]any{}

		if id, ok := data["id"]; ok {
			props["id"] = id
		}

		if nr, ok := data["number"]; ok {
			props["number"] = nr
		}

		return props, nil

	case OrganizationNamespace, UserNamespace:
		props := map[string]any{}

		if login, ok := data["login"]; ok {
			props["login"] = login
		}

		if name, ok := data["name"]; ok {
			props["name"] = name
		}

		return props, nil

	case RepositoryNamespace:
		props := map[string]any{}

		if owner, ok := data["owner"].(map[string]any); ok {
			if login, ok := owner["login"]; ok {
				props["owner"] = login
			}
		}

		if name, ok := data["name"]; ok {
			props["repo"] = name
		}

		if defaultBranch, ok := data["default_branch"]; ok {
			props["default_branch"] = defaultBranch
		}

		return props, nil
	}

	return nil, provider.ErrNonDerivable
}


================================================
FILE: provider/github/github_test.go
================================================
package github_test

import (
	"testing"

	"github.com/reposaur/reposaur/provider"
	"github.com/reposaur/reposaur/provider/github"
)

func TestDeriveNamespace(t *testing.T) {
	gh := github.NewProvider(nil)

	testData := map[provider.Namespace]map[string]any{
		github.IssueNamespace: {
			"reactions": ":+1:",
			"closed_by": "crqra",
		},
		github.OrganizationNamespace: {
			"login":       "reposaur",
			"members_url": "https://reposaur.com",
		},
		github.PullRequestNamespace: {
			"base": "main",
			"head": "feat",
		},
		github.RepositoryNamespace: {
			"owner":     "reposaur",
			"full_name": "reposaur/reposaur",
		},
		github.UserNamespace: {
			"login":    "crqra",
			"hireable": true,
		},
	}

	for expected, data := range testData {
		namespace, err := gh.DeriveNamespace(data)
		if err != nil {
			t.Fatalf("testing %s: %s", expected, err)
		}

		if namespace != expected {
			t.Fatalf("expected namespace to be '%s' got '%s'", expected, namespace)
		}
	}
}


================================================
FILE: provider/github/internal/builtin/graphql.go
================================================
package builtin

import (
	"bytes"
	"encoding/json"
	"fmt"
	"net/http"

	"github.com/hashicorp/go-retryablehttp"
	"github.com/open-policy-agent/opa/ast"
	"github.com/open-policy-agent/opa/rego"
	"github.com/open-policy-agent/opa/types"
	"github.com/reposaur/reposaur/provider/github/client"
)

type GraphQL struct {
	Client *client.Client
}

func (gql GraphQL) Func() *rego.Function {
	return &rego.Function{
		Name: "github.graphql",
		Decl: types.NewFunction(
			types.Args(
				types.S,
				types.NewObject(nil, types.NewDynamicProperty(types.S, types.A)),
			),
			types.A,
		),
		Memoize: true,
	}
}

func (gql GraphQL) Impl(_ rego.BuiltinContext, terms []*ast.Term) (*ast.Term, error) {
	req, err := gql.argsToRequest(terms)
	if err != nil {
		return nil, err
	}

	resp, err := gql.Client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var finalResp response

	dec := json.NewDecoder(resp.Body)
	if err := dec.Decode(&finalResp.Body); err != nil {
		return nil, err
	}

	finalResp.StatusCode = resp.StatusCode

	if finalResp.StatusCode == http.StatusForbidden {
		b := finalResp.Body.(map[string]interface{})
		return nil, fmt.Errorf("forbidden: %s", b["message"])
	}

	val, err := ast.InterfaceToValue(finalResp)
	if err != nil {
		return nil, err
	}

	return ast.NewTerm(val), nil
}

func (gql GraphQL) argsToRequest(terms []*ast.Term) (*retryablehttp.Request, error) {
	// FIXME: Function receives 2 arguments but terms includes one additional at last index
	if len(terms) != 3 {
		return nil, fmt.Errorf("wrong number of arguments, expected 2 got %d", len(terms)-1)
	}

	var (
		query string
		vars  map[string]any
	)

	if err := ast.As(terms[0].Value, &query); err != nil {
		return nil, err
	}

	if err := ast.As(terms[1].Value, &vars); err != nil {
		return nil, err
	}

	body := map[string]any{
		"query":     query,
		"variables": vars,
	}

	buf := &bytes.Buffer{}
	enc := json.NewEncoder(buf)
	enc.SetEscapeHTML(false)
	if err := enc.Encode(body); err != nil {
		return nil, err
	}

	return gql.Client.NewRequest(http.MethodPost, "/graphql", buf)
}


================================================
FILE: provider/github/internal/builtin/request.go
================================================
package builtin

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/url"
	"regexp"
	"strconv"
	"strings"

	"github.com/hashicorp/go-retryablehttp"
	"github.com/open-policy-agent/opa/ast"
	"github.com/open-policy-agent/opa/rego"
	"github.com/open-policy-agent/opa/types"
	"github.com/reposaur/reposaur/provider/github/client"
)

type Request struct {
	Client *client.Client
}

func (r Request) Func() *rego.Function {
	return &rego.Function{
		Name: "github.request",
		Decl: types.NewFunction(
			types.Args(
				types.S,
				types.NewObject(nil, types.NewDynamicProperty(types.S, types.A)),
			),
			types.A,
		),
		Memoize: true,
	}
}

func (r Request) Impl(_ rego.BuiltinContext, terms []*ast.Term) (*ast.Term, error) {
	req, err := r.argsToRequest(terms)
	if err != nil {
		return nil, err
	}

	resp, err := r.Client.Do(req)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()

	var finalResp response

	dec := json.NewDecoder(resp.Body)
	if err := dec.Decode(&finalResp.Body); err != nil {
		return nil, err
	}

	finalResp.StatusCode = resp.StatusCode

	if finalResp.StatusCode == http.StatusForbidden {
		b := finalResp.Body.(map[string]interface{})
		return nil, fmt.Errorf("forbidden: %s", b["message"])
	}

	val, err := ast.InterfaceToValue(finalResp)
	if err != nil {
		return nil, err
	}

	return ast.NewTerm(val), nil
}

func (r Request) argsToRequest(terms []*ast.Term) (*retryablehttp.Request, error) {
	// FIXME: Function receives 2 arguments but terms includes one additional at last index
	if len(terms) != 3 {
		return nil, fmt.Errorf("wrong number of arguments, expected 2 got %d", len(terms)-1)
	}

	var (
		path string
		data map[string]any
	)

	if err := ast.As(terms[0].Value, &path); err != nil {
		return nil, err
	}

	if err := ast.As(terms[1].Value, &data); err != nil {
		return nil, err
	}

	method, path, err := r.parsePath(path)
	if err != nil {
		return nil, err
	}

	if method != http.MethodGet {
		return nil, fmt.Errorf("only GET requests are supported, got '%s'", method)
	}

	pathParams := r.parsePathParams(path)

	for _, p := range pathParams {
		v, err := r.valueToString(data[p])
		if err != nil {
			return nil, err
		}

		path = strings.Replace(path, "{"+p+"}", v, 1)
		delete(data, p)
	}

	qs := url.Values{}

	for k, v := range data {
		v, err := r.valueToString(v)
		if err != nil {
			return nil, err
		}

		qs.Add(k, v)
		delete(data, k)
	}

	u, err := url.Parse(path)
	if err != nil {
		return nil, err
	}

	u.RawQuery = qs.Encode()

	return r.Client.NewRequest(method, u.String(), nil)
}

func (r Request) parsePath(p string) (string, string, error) {
	pathParts := strings.Split(p, " ")

	if len(pathParts) != 2 {
		return "", "", fmt.Errorf("wrong number of parts in path, expected 2 got %d", len(pathParts))
	}

	var (
		method = strings.ToUpper(pathParts[0])
		path   = pathParts[1]
	)

	return method, path, nil
}

func (r Request) parsePathParams(path string) []string {
	regex := regexp.MustCompile(`{[a-z]+}`)
	matches := regex.FindAllString(path, -1)

	var params []string
	for _, v := range matches {
		p := strings.Replace(v, "{", "", 1)
		p = strings.Replace(p, "}", "", 1)
		params = append(params, p)
	}

	return params
}

func (r Request) valueToString(v interface{}) (string, error) {
	switch tv := v.(type) {
	case string:
		return tv, nil

	case json.Number:
		return tv.String(), nil

	case int64:
		return strconv.Itoa(int(tv)), nil
	}

	return "", fmt.Errorf("parse error: can't parse '%v' to string", v)
}


================================================
FILE: provider/github/internal/builtin/response.go
================================================
package builtin

type response struct {
	StatusCode int         `json:"status"`
	Body       interface{} `json:"body"`
}


================================================
FILE: provider/provider.go
================================================
package provider

import (
	"encoding/json"
	"errors"
	"reflect"

	"github.com/open-policy-agent/opa/ast"
	"github.com/open-policy-agent/opa/rego"
)

var ErrNonDerivable = errors.New("data is non derivable")

type Namespace string

// DataDeriver is the interface that provides functions to derive a policy
// namespace and report properties from input data for a specific provider.
type DataDeriver interface {
	DeriveNamespace(map[string]any) (Namespace, error)
	DeriveProperties(Namespace, map[string]any) (map[string]any, error)
}

// Provider is the interface that provides the functions required to work with
// a specific provider, namely a function to register built-in functions in
// the policy engine and functions to derive required information from input data.
// See DataDeriver.
type Provider interface {
	DataDeriver

	Builtins() []Builtin
}

// Builtin is represents a built-in function in the policy engine. It specifies
// the function signature and the function implementation.
type Builtin interface {
	Func() *rego.Function
	Impl(rego.BuiltinContext, []*ast.Term) (*ast.Term, error)
}

func DeriveNamespace(deriver DataDeriver, data any) (Namespace, error) {
	m, err := dataToMap(data)
	if err != nil {
		return "", err
	}

	return deriver.DeriveNamespace(m)
}

func DeriveProperties(deriver DataDeriver, namespace Namespace, data any) (map[string]any, error) {
	m, err := dataToMap(data)
	if err != nil {
		return nil, err
	}

	return deriver.DeriveProperties(namespace, m)
}

func dataToMap(data any) (map[string]any, error) {
	val := reflect.ValueOf(data)

	// We can never derive anything from a slice, only from maps or structures
	if val.Kind() == reflect.Slice {
		return nil, ErrNonDerivable
	}

	// If data is already a map we just convert it to map[string]any
	if val.Kind() == reflect.Map {
		m := make(map[string]any, val.Len())
		for _, k := range val.MapKeys() {
			if k.Kind() == reflect.String {
				m[k.String()] = val.MapIndex(k).Interface()
			}
		}
		return m, nil
	}

	if val.Kind() != reflect.Struct {
		return nil, ErrNonDerivable
	}

	// Here we have a structure, we rely on json package to convert it into
	// a map for us.
	rawData, err := json.Marshal(data)
	if err != nil {
		return nil, err
	}

	var m map[string]any

	if err := json.Unmarshal(rawData, &m); err != nil {
		return nil, err
	}

	return m, nil
}


================================================
FILE: provider/provider_test.go
================================================
package provider

import (
	"errors"
	"testing"
)

func TestMapDataToMap(t *testing.T) {
	dataMap := map[string]any{
		"foo": "bar",
		"bar": 10,
	}

	m, err := dataToMap(dataMap)
	if err != nil {
		t.Error(err)
	}

	if foo, ok := m["foo"]; !ok || foo != "bar" {
		t.Fail()
	}

	if bar, ok := m["bar"]; !ok || bar != 10 {
		t.Fail()
	}
}

func TestStructDataToMap(t *testing.T) {
	dataStruct := struct {
		Foo string `json:"foo"`
		Bar int    `json:"bar"`
	}{
		Foo: "bar",
		Bar: 10,
	}

	m, err := dataToMap(dataStruct)
	if err != nil {
		t.Error(err)
	}

	if foo, ok := m["foo"]; !ok || foo != "bar" {
		t.Fail()
	}

	// JSON numbers are stored as float64 when converting to interface{}
	// See https://pkg.go.dev/encoding/json#Unmarshal
	if bar, ok := m["bar"]; !ok || bar != 10.0 {
		t.Fail()
	}
}

func TestAnyDataToMap(t *testing.T) {
	_, err := dataToMap(10)
	if !errors.Is(err, ErrNonDerivable) {
		t.Errorf("expected error '%s' got '%s'", ErrNonDerivable, err)
	}

	_, err = dataToMap("foo")
	if !errors.Is(err, ErrNonDerivable) {
		t.Errorf("expected error '%s' got '%s'", ErrNonDerivable, err)
	}

	_, err = dataToMap([]string{"foo", "bar"})
	if !errors.Is(err, ErrNonDerivable) {
		t.Errorf("expected error '%s' got '%s'", ErrNonDerivable, err)
	}
}


================================================
FILE: scripts/completions.sh
================================================
#!/bin/sh
set -e
rm -rf completions
mkdir completions
for sh in bash zsh fish; do
	go run cmd/rsr/rsr.go completion "$sh" > "completions/rsr.$sh"
done
Download .txt
gitextract_j1gkgj0k/

├── .github/
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── bug_report.yml
│   │   ├── config.yml
│   │   └── feature_request.yml
│   ├── codeowners
│   ├── dependabot.yml
│   └── workflows/
│       └── test.yml
├── .gitignore
├── .goreleaser.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── Taskfile.yaml
├── action.yml
├── cmd/
│   └── rsr/
│       ├── internal/
│       │   ├── bundle/
│       │   │   └── bundle.go
│       │   ├── cmdutil/
│       │   │   ├── env.go
│       │   │   ├── flag.go
│       │   │   ├── io.go
│       │   │   └── logger.go
│       │   ├── exec/
│       │   │   └── exec.go
│       │   ├── root/
│       │   │   └── root.go
│       │   └── test/
│       │       └── test.go
│       └── rsr.go
├── go.mod
├── go.sum
├── install.sh
├── internal/
│   ├── build/
│   │   └── build.go
│   └── policy/
│       ├── engine.go
│       └── errors.go
├── pkg/
│   ├── output/
│   │   ├── report.go
│   │   └── sarif.go
│   └── sdk/
│       └── sdk.go
├── provider/
│   ├── github/
│   │   ├── client/
│   │   │   └── client.go
│   │   ├── github.go
│   │   ├── github_test.go
│   │   └── internal/
│   │       └── builtin/
│   │           ├── graphql.go
│   │           ├── request.go
│   │           └── response.go
│   ├── provider.go
│   └── provider_test.go
└── scripts/
    └── completions.sh
Download .txt
SYMBOL INDEX (113 symbols across 23 files)

FILE: cmd/rsr/internal/bundle/bundle.go
  type bundleParams (line 12) | type bundleParams struct
  function NewCmd (line 17) | func NewCmd() *cobra.Command {

FILE: cmd/rsr/internal/cmdutil/env.go
  function getEnv (line 11) | func getEnv(keys ...string) string {
  function getInt64Env (line 23) | func getInt64Env(keys ...string) int64 {

FILE: cmd/rsr/internal/cmdutil/flag.go
  type GitHubClientOptions (line 8) | type GitHubClientOptions struct
  function AddPolicyPathsFlag (line 25) | func AddPolicyPathsFlag(flags *pflag.FlagSet, p *[]string) {
  function AddOutputFlag (line 29) | func AddOutputFlag(flags *pflag.FlagSet, p *string) {
  function AddTraceFlag (line 33) | func AddTraceFlag(flags *pflag.FlagSet, p *bool) {
  function AddVerboseFlag (line 37) | func AddVerboseFlag(flags *pflag.FlagSet, p *bool) {
  function AddExperimentalFlag (line 41) | func AddExperimentalFlag(flags *pflag.FlagSet, p *bool) {
  function AddGitHubFlags (line 45) | func AddGitHubFlags(flags *pflag.FlagSet, p *GitHubClientOptions) {

FILE: cmd/rsr/internal/cmdutil/io.go
  function GetInputReader (line 14) | func GetInputReader(ctx context.Context, filename string) (r io.ReadClos...
  function GetOutputWriter (line 37) | func GetOutputWriter(ctx context.Context, filename string) (w io.WriteCl...

FILE: cmd/rsr/internal/cmdutil/logger.go
  function NewLogger (line 12) | func NewLogger(verbose bool) zerolog.Logger {

FILE: cmd/rsr/internal/exec/exec.go
  type execParams (line 21) | type execParams struct
  function NewCmd (line 29) | func NewCmd() *cobra.Command {
  function runExec (line 104) | func runExec(ctx context.Context, rsr *sdk.Reposaur, inReader io.ReadClo...
  function newGitHubProvider (line 200) | func newGitHubProvider(ctx context.Context, opts *cmdutil.GitHubClientOp...

FILE: cmd/rsr/internal/root/root.go
  type rootParams (line 12) | type rootParams struct
  function NewCmd (line 16) | func NewCmd() *cobra.Command {

FILE: cmd/rsr/internal/test/test.go
  type testParams (line 14) | type testParams struct
  function NewCmd (line 20) | func NewCmd() *cobra.Command {
  function runTest (line 66) | func runTest(ctx context.Context, rsr *sdk.Reposaur) {

FILE: cmd/rsr/rsr.go
  function main (line 10) | func main() {

FILE: internal/build/build.go
  function init (line 10) | func init() {

FILE: internal/policy/engine.go
  type Option (line 17) | type Option
  type Engine (line 19) | type Engine struct
    method Namespaces (line 67) | func (e *Engine) Namespaces() []string {
    method Compiler (line 84) | func (e *Engine) Compiler() *ast.Compiler {
    method Modules (line 89) | func (e *Engine) Modules() map[string]*ast.Module {
    method Check (line 93) | func (e *Engine) Check(ctx context.Context, namespace string, input in...
    method check (line 102) | func (e *Engine) check(ctx context.Context, namespace string, input in...
    method queryRule (line 152) | func (e *Engine) queryRule(ctx context.Context, rule *output.Rule, inp...
    method querySkip (line 170) | func (e *Engine) querySkip(ctx context.Context, rule *output.Rule, inp...
    method buildRegoInstance (line 188) | func (e *Engine) buildRegoInstance(query string, input interface{}) *r...
  function Load (line 25) | func Load(_ context.Context, policyPaths []string, opts ...Option) (*Eng...
  function WithTracingEnabled (line 60) | func WithTracingEnabled(enabled bool) Option {
  function isRegoFile (line 199) | func isRegoFile(_ string, info os.FileInfo, _ int) bool {

FILE: internal/policy/errors.go
  type ErrPolicyLoad (line 5) | type ErrPolicyLoad struct
    method Error (line 9) | func (e *ErrPolicyLoad) Error() string {
  type ErrNoPolicies (line 13) | type ErrNoPolicies struct
    method Error (line 17) | func (e *ErrNoPolicies) Error() string {

FILE: pkg/output/report.go
  type Severity (line 10) | type Severity
  constant ErrorSeverity (line 13) | ErrorSeverity   = "error"
  constant WarningSeverity (line 14) | WarningSeverity = "warning"
  constant NoteSeverity (line 15) | NoteSeverity    = "note"
  type Report (line 30) | type Report struct
    method AddRule (line 37) | func (r *Report) AddRule(rule *Rule) {
    method AddResult (line 42) | func (r *Report) AddResult(result *Result) {
  type ReportProperties (line 46) | type ReportProperties
  type Result (line 48) | type Result struct
  type Rule (line 55) | type Rule struct
    method CausesFailure (line 132) | func (r Rule) CausesFailure() bool {
    method UID (line 136) | func (r Rule) UID() string {
  function NewRule (line 66) | func NewRule(namespace string, rule *ast.Rule, as *ast.Annotations) (*Ru...

FILE: pkg/output/sarif.go
  function NewSarifReport (line 9) | func NewSarifReport(report Report) (*sarif.Report, error) {

FILE: pkg/sdk/sdk.go
  type Option (line 30) | type Option
  type Reposaur (line 35) | type Reposaur struct
    method Logger (line 106) | func (sdk Reposaur) Logger() zerolog.Logger {
    method Engine (line 111) | func (sdk Reposaur) Engine() *policy.Engine {
    method Check (line 117) | func (sdk Reposaur) Check(ctx context.Context, data interface{}) (outp...
    method Test (line 154) | func (sdk Reposaur) Test(ctx context.Context) ([]*tester.Result, error) {
    method Bundle (line 194) | func (sdk Reposaur) Bundle(ctx context.Context, paths []string, out io...
  function New (line 55) | func New(ctx context.Context, policyPaths []string, opts ...Option) (*Re...
  function WithProvider (line 84) | func WithProvider(provider provider.Provider) Option {
  function WithLogger (line 91) | func WithLogger(logger zerolog.Logger) Option {
  function WithTracingEnabled (line 99) | func WithTracingEnabled(enabled bool) Option {

FILE: provider/github/client/client.go
  constant DefaultBaseURL (line 14) | DefaultBaseURL = "https://api.github.com"
  type Client (line 17) | type Client struct
    method Client (line 66) | func (c Client) Client() *http.Client {
    method Token (line 70) | func (c Client) Token(ctx context.Context) (string, error) {
    method NewRequest (line 78) | func (c Client) NewRequest(method, path string, rawBody any) (*retryab...
    method Do (line 98) | func (c Client) Do(req *retryablehttp.Request) (*http.Response, error) {
  function NewClient (line 25) | func NewClient(httpClient *http.Client) *Client {
  function NewTokenClient (line 35) | func NewTokenClient(ctx context.Context, token string) *Client {
  function NewAppClient (line 48) | func NewAppClient(_ context.Context, baseURL string, appID, installation...
  function newRetryableClient (line 102) | func newRetryableClient(httpClient *http.Client) *retryablehttp.Client {

FILE: provider/github/github.go
  constant IssueNamespace (line 10) | IssueNamespace        provider.Namespace = "github.issue"
  constant OrganizationNamespace (line 11) | OrganizationNamespace provider.Namespace = "github.organization"
  constant PullRequestNamespace (line 12) | PullRequestNamespace  provider.Namespace = "github.pull_request"
  constant RepositoryNamespace (line 13) | RepositoryNamespace   provider.Namespace = "github.repository"
  constant UserNamespace (line 14) | UserNamespace         provider.Namespace = "github.user"
  type GitHub (line 17) | type GitHub struct
    method DeriveNamespace (line 46) | func (gh GitHub) DeriveNamespace(data map[string]any) (provider.Namesp...
    method DeriveProperties (line 50) | func (gh GitHub) DeriveProperties(namespace provider.Namespace, data m...
    method Builtins (line 54) | func (gh GitHub) Builtins() []provider.Builtin {
  function NewProvider (line 23) | func NewProvider(c *client.Client) *GitHub {
  type DataDeriver (line 58) | type DataDeriver struct
    method DeriveNamespace (line 62) | func (d DataDeriver) DeriveNamespace(data map[string]any) (provider.Na...
    method DeriveProperties (line 82) | func (d DataDeriver) DeriveProperties(namespace provider.Namespace, da...

FILE: provider/github/github_test.go
  function TestDeriveNamespace (line 10) | func TestDeriveNamespace(t *testing.T) {

FILE: provider/github/internal/builtin/graphql.go
  type GraphQL (line 16) | type GraphQL struct
    method Func (line 20) | func (gql GraphQL) Func() *rego.Function {
    method Impl (line 34) | func (gql GraphQL) Impl(_ rego.BuiltinContext, terms []*ast.Term) (*as...
    method argsToRequest (line 68) | func (gql GraphQL) argsToRequest(terms []*ast.Term) (*retryablehttp.Re...

FILE: provider/github/internal/builtin/request.go
  type Request (line 19) | type Request struct
    method Func (line 23) | func (r Request) Func() *rego.Function {
    method Impl (line 37) | func (r Request) Impl(_ rego.BuiltinContext, terms []*ast.Term) (*ast....
    method argsToRequest (line 71) | func (r Request) argsToRequest(terms []*ast.Term) (*retryablehttp.Requ...
    method parsePath (line 133) | func (r Request) parsePath(p string) (string, string, error) {
    method parsePathParams (line 148) | func (r Request) parsePathParams(path string) []string {
    method valueToString (line 162) | func (r Request) valueToString(v interface{}) (string, error) {

FILE: provider/github/internal/builtin/response.go
  type response (line 3) | type response struct

FILE: provider/provider.go
  type Namespace (line 14) | type Namespace
  type DataDeriver (line 18) | type DataDeriver interface
  type Provider (line 27) | type Provider interface
  type Builtin (line 35) | type Builtin interface
  function DeriveNamespace (line 40) | func DeriveNamespace(deriver DataDeriver, data any) (Namespace, error) {
  function DeriveProperties (line 49) | func DeriveProperties(deriver DataDeriver, namespace Namespace, data any...
  function dataToMap (line 58) | func dataToMap(data any) (map[string]any, error) {

FILE: provider/provider_test.go
  function TestMapDataToMap (line 8) | func TestMapDataToMap(t *testing.T) {
  function TestStructDataToMap (line 28) | func TestStructDataToMap(t *testing.T) {
  function TestAnyDataToMap (line 53) | func TestAnyDataToMap(t *testing.T) {
Condensed preview — 42 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (129K chars).
[
  {
    "path": ".github/FUNDING.yml",
    "chars": 26,
    "preview": "github: [reposaur, crqra]\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.yml",
    "chars": 1446,
    "preview": "name: Bug Report\ndescription: File a bug report\n\ntitle: \"[Bug]: \"\nlabels: [\"bug\", \"triage\"]\n\nbody:\n  - type: markdown\n  "
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "chars": 156,
    "preview": "blank_issues_enabled: true\ncontact_links:\n  - name: Ask a question\n    url: https://github.com/orgs/reposaur/discussions"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.yml",
    "chars": 1282,
    "preview": "name: Feature Request\ndescription: Suggest a new idea or feature to add to Reposaur\n\ntitle: \"[Feature]: \"\nlabels: [\"enha"
  },
  {
    "path": ".github/codeowners",
    "chars": 8,
    "preview": "* @crqra"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 109,
    "preview": "version: 2\nupdates:\n  - package-ecosystem: \"gomod\"\n    directory: \"/\"\n    schedule:\n      interval: \"weekly\"\n"
  },
  {
    "path": ".github/workflows/test.yml",
    "chars": 1901,
    "preview": "name: Test\n\non:\n  push:\n    branches:\n      - main\n  pull_request:\n\nenv:\n  GO111MODULE: on\n\njobs:\n  golangci-lint:\n    n"
  },
  {
    "path": ".gitignore",
    "chars": 146,
    "preview": "# Used for local tests only\n/config.yaml\n/policy/\n/testdata/events/_*.json\ndist/\nbin/\n\n# Generated\n/completions\n\n# Edito"
  },
  {
    "path": ".goreleaser.yml",
    "chars": 3209,
    "preview": "before:\n  hooks:\n    - go mod tidy\n    - go vet ./...\n    - ./scripts/completions.sh\n\nbuilds:\n  - id: rsr\n    binary: rs"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "chars": 5218,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nWe as members, contributors, and leaders pledge to make participa"
  },
  {
    "path": "CONTRIBUTING.md",
    "chars": 2850,
    "preview": "# Contributing\n\nBeforehand, thank you for considering contributing to Reposaur! We welcome and\nappreciate any help we ca"
  },
  {
    "path": "LICENSE",
    "chars": 1096,
    "preview": "MIT License\n\nCopyright (c) 2022 João Cerqueira and Reposaur contributors\n\nPermission is hereby granted, free of charge, "
  },
  {
    "path": "README.md",
    "chars": 5432,
    "preview": "<div align=\"center\">\n\n[![logo][logo]][website]\n\n# Reposaur\n\n[![go-report][go-report-badge]][go-report]\n[![tests-workflow"
  },
  {
    "path": "Taskfile.yaml",
    "chars": 1046,
    "preview": "# https://taskfile.dev\n\nversion: \"3\"\n\ntasks:\n  deps:\n    run: once\n    cmds:\n      - go mod tidy\n    silent: true\n\n  bui"
  },
  {
    "path": "action.yml",
    "chars": 520,
    "preview": "name: Reposaur\nauthor: Reposaur Authors\ndescription: Audit your GitHub data using custom policies written in Rego\n\nbrand"
  },
  {
    "path": "cmd/rsr/internal/bundle/bundle.go",
    "chars": 1544,
    "preview": "package bundle\n\nimport (\n\t\"os\"\n\n\t\"github.com/reposaur/reposaur/cmd/rsr/internal/cmdutil\"\n\t\"github.com/reposaur/reposaur/"
  },
  {
    "path": "cmd/rsr/internal/cmdutil/env.go",
    "chars": 714,
    "preview": "package cmdutil\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strconv\"\n)\n\n// getEnv looks up every key in keys in the environment variables a"
  },
  {
    "path": "cmd/rsr/internal/cmdutil/flag.go",
    "chars": 1982,
    "preview": "package cmdutil\n\nimport (\n\tgithubclient \"github.com/reposaur/reposaur/provider/github/client\"\n\t\"github.com/spf13/pflag\"\n"
  },
  {
    "path": "cmd/rsr/internal/cmdutil/io.go",
    "chars": 1255,
    "preview": "package cmdutil\n\nimport (\n\t\"context\"\n\t\"io\"\n\t\"os\"\n\n\t\"github.com/rs/zerolog\"\n)\n\n// GetInputReader returns an io.ReadCloser"
  },
  {
    "path": "cmd/rsr/internal/cmdutil/logger.go",
    "chars": 458,
    "preview": "package cmdutil\n\nimport (\n\t\"os\"\n\n\t\"github.com/rs/zerolog\"\n)\n\n// NewLogger returns a new logger that outputs to\n// the st"
  },
  {
    "path": "cmd/rsr/internal/exec/exec.go",
    "chars": 5005,
    "preview": "package exec\n\nimport (\n\t\"context\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io\"\n\t\"os\"\n\t\"sync\"\n\t\"time\"\n\n\t\"github.com/reposaur/reposaur"
  },
  {
    "path": "cmd/rsr/internal/root/root.go",
    "chars": 888,
    "preview": "package root\n\nimport (\n\t\"github.com/reposaur/reposaur/cmd/rsr/internal/bundle\"\n\t\"github.com/reposaur/reposaur/cmd/rsr/in"
  },
  {
    "path": "cmd/rsr/internal/test/test.go",
    "chars": 2056,
    "preview": "package test\n\nimport (\n\t\"context\"\n\t\"os\"\n\t\"time\"\n\n\t\"github.com/reposaur/reposaur/cmd/rsr/internal/cmdutil\"\n\t\"github.com/r"
  },
  {
    "path": "cmd/rsr/rsr.go",
    "chars": 251,
    "preview": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\t\"github.com/reposaur/reposaur/cmd/rsr/internal/root\"\n)\n\nfunc main() {\n\tif err := r"
  },
  {
    "path": "go.mod",
    "chars": 1642,
    "preview": "module github.com/reposaur/reposaur\n\ngo 1.18\n\nrequire (\n\tgithub.com/bradleyfalzon/ghinstallation/v2 v2.1.0\n\tgithub.com/h"
  },
  {
    "path": "go.sum",
    "chars": 48142,
    "preview": "cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=\ncloud.google.com/go v0.34.0/go.mod h1"
  },
  {
    "path": "install.sh",
    "chars": 1179,
    "preview": "#!/bin/sh\nset -e\n\nRELEASES_URL=\"https://github.com/reposaur/reposaur/releases\"\nFILE_BASENAME=\"reposaur\"\n\ntest -z \"$VERSI"
  },
  {
    "path": "internal/build/build.go",
    "chars": 269,
    "preview": "package build\n\nimport (\n\t\"runtime/debug\"\n)\n\n// Version is dynamically set by the toolchain.\nvar Version = \"DEV\"\n\nfunc in"
  },
  {
    "path": "internal/policy/engine.go",
    "chars": 4746,
    "preview": "package policy\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/open-policy-agent/opa/ast\"\n\t\"github.com/open-p"
  },
  {
    "path": "internal/policy/errors.go",
    "chars": 339,
    "preview": "package policy\n\nimport \"fmt\"\n\ntype ErrPolicyLoad struct {\n\tloaderError error\n}\n\nfunc (e *ErrPolicyLoad) Error() string {"
  },
  {
    "path": "pkg/output/report.go",
    "chars": 2898,
    "preview": "package output\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/open-policy-agent/opa/ast\"\n)\n\ntype Severity string\n\nconst (\n\tEr"
  },
  {
    "path": "pkg/output/sarif.go",
    "chars": 1435,
    "preview": "package output\n\nimport (\n\t\"strings\"\n\n\t\"github.com/owenrumney/go-sarif/v2/sarif\"\n)\n\nfunc NewSarifReport(report Report) (*"
  },
  {
    "path": "pkg/sdk/sdk.go",
    "chars": 4999,
    "preview": "package sdk\n\nimport (\n\t\"bytes\"\n\t\"context\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/open-policy-agent/opa/co"
  },
  {
    "path": "provider/github/client/client.go",
    "chars": 2203,
    "preview": "package client\n\nimport (\n\t\"context\"\n\t\"net/http\"\n\t\"net/url\"\n\n\t\"github.com/bradleyfalzon/ghinstallation/v2\"\n\t\"github.com/h"
  },
  {
    "path": "provider/github/github.go",
    "chars": 3027,
    "preview": "package github\n\nimport (\n\t\"github.com/reposaur/reposaur/provider\"\n\t\"github.com/reposaur/reposaur/provider/github/client\""
  },
  {
    "path": "provider/github/github_test.go",
    "chars": 975,
    "preview": "package github_test\n\nimport (\n\t\"testing\"\n\n\t\"github.com/reposaur/reposaur/provider\"\n\t\"github.com/reposaur/reposaur/provid"
  },
  {
    "path": "provider/github/internal/builtin/graphql.go",
    "chars": 2091,
    "preview": "package builtin\n\nimport (\n\t\"bytes\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\n\t\"github.com/hashicorp/go-retryablehttp\"\n\t\"githu"
  },
  {
    "path": "provider/github/internal/builtin/request.go",
    "chars": 3489,
    "preview": "package builtin\n\nimport (\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"net/http\"\n\t\"net/url\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"strings\"\n\n\t\"github.com/h"
  },
  {
    "path": "provider/github/internal/builtin/response.go",
    "chars": 120,
    "preview": "package builtin\n\ntype response struct {\n\tStatusCode int         `json:\"status\"`\n\tBody       interface{} `json:\"body\"`\n}\n"
  },
  {
    "path": "provider/provider.go",
    "chars": 2361,
    "preview": "package provider\n\nimport (\n\t\"encoding/json\"\n\t\"errors\"\n\t\"reflect\"\n\n\t\"github.com/open-policy-agent/opa/ast\"\n\t\"github.com/o"
  },
  {
    "path": "provider/provider_test.go",
    "chars": 1263,
    "preview": "package provider\n\nimport (\n\t\"errors\"\n\t\"testing\"\n)\n\nfunc TestMapDataToMap(t *testing.T) {\n\tdataMap := map[string]any{\n\t\t\""
  },
  {
    "path": "scripts/completions.sh",
    "chars": 150,
    "preview": "#!/bin/sh\nset -e\nrm -rf completions\nmkdir completions\nfor sh in bash zsh fish; do\n\tgo run cmd/rsr/rsr.go completion \"$sh"
  }
]

About this extraction

This page contains the full source code of the reposaur/reposaur GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 42 files (117.1 KB), approximately 46.4k tokens, and a symbol index with 113 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!