[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\n\nexecutors:\n  linuxgo:\n    docker:\n      - image: cimg/go:1.23\n\ncommands:\n  go-build:\n    parameters:\n      os:\n        description: Target operating system\n        type: enum\n        enum: [\"linux\", \"darwin\", \"windows\"]\n        default: \"linux\"\n      arch:\n        description: Target architecture\n        type: enum\n        enum: [\"386\", \"amd64\", \"arm64\"]\n        default: \"amd64\"\n      suffix:\n        description: Optional suffix\n        type: string\n        default: \"\"\n    steps:\n      - run: |\n          GOOS=<< parameters.os >> \\\n          GOARCH=<< parameters.arch >> \\\n          CGO_ENABLED=0 \\\n          go build -ldflags \"-X main.Version=${CIRCLE_TAG}\" \\\n          -o $GOPATH/bin/buildevents-<< parameters.os >>-<< parameters.arch >><< parameters.suffix >> \\\n          ./...\n\njobs:\n  test:\n    executor: linuxgo\n    steps:\n      - checkout\n      - run:\n          name: go_test\n          command: go test -v ./...\n      - run: make verify-licenses\n\n  build:\n    executor: linuxgo\n    steps:\n      - checkout\n      - go-build:\n          os: linux\n          arch: \"386\"\n      - go-build:\n          os: linux\n          arch: amd64\n      - go-build:\n          os: darwin\n          arch: amd64\n      - go-build:\n          os: darwin\n          arch: arm64\n      - go-build:\n          os: linux\n          arch: arm64\n      - go-build:\n          os: windows\n          arch: \"386\"\n          suffix: \".exe\"\n      - go-build:\n          os: windows\n          arch: amd64\n          suffix: \".exe\"\n      - go-build:\n          os: windows\n          arch: arm64\n          suffix: \".exe\"\n      - run: mkdir -v artifacts; cp -v $GOPATH/bin/buildevents-* artifacts/\n      - run: tar -cvf artifacts/buildevents.tar artifacts/buildevents-*\n      - persist_to_workspace:\n          root: artifacts\n          paths:\n            - buildevents.tar\n      - store_artifacts:\n          path: artifacts/\n\n  smoketest:\n    executor: linuxgo\n    steps:\n      - attach_workspace:\n          at: artifacts\n      - run: tar -xvf artifacts/buildevents.tar\n      - run:\n          name: \"Subcommand success = success\"\n          command: |\n            result=$(artifacts/buildevents-linux-amd64 cmd buildId stepId name -- true >/dev/null && echo \"worked\")\n            if [ \"$result\" != \"worked\" ]; then\n              exit 1\n            fi\n      - run:\n          name: \"Subcommand failure = failure\"\n          command: |\n            result=$(artifacts/buildevents-linux-amd64 cmd buildId stepId name -- false > /dev/null || echo \"worked\" )\n            if [ \"$result\" != \"worked\" ]; then\n              exit 1\n            fi\n\n  publish:\n    docker:\n      - image: cibuilds/github:0.13.0\n    steps:\n      - attach_workspace:\n          at: artifacts\n      - run:\n          name: \"Publish Release on GitHub\"\n          command: |\n            echo \"about to publish to tag ${CIRCLE_TAG}\"\n            tar -xvf artifacts/buildevents.tar\n            rm -rf artifacts/buildevents.tar\n            ls -l ./artifacts\n            ghr -draft -t ${GITHUB_TOKEN} -u ${CIRCLE_PROJECT_USERNAME} -r ${CIRCLE_PROJECT_REPONAME} -c ${CIRCLE_SHA1} ${CIRCLE_TAG} ./artifacts\n\nworkflows:\n  build:\n    jobs:\n      - test:\n          filters:\n            tags:\n              only: /.*/\n      - build:\n          requires:\n            - test\n          filters:\n            tags:\n              only: /.*/\n      - smoketest:\n          requires:\n            - build\n          filters:\n            tags:\n              only: /.*/\n      - publish:\n          context: Honeycomb Secrets for Public Repos\n          requires:\n            - smoketest\n          filters:\n            tags:\n              only: /^v.*/\n            branches:\n              ignore: /.*/\n"
  },
  {
    "path": ".github/CODEOWNERS",
    "content": "# Code owners file.\n# This file controls who is tagged for review for any given pull request.\n\n# For anything not explicitly taken by someone else:\n* @honeycombio/pipeline-team\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/bug_report.md",
    "content": "---\nname: Bug report\nabout: Let us know if something is not working as expected\ntitle: ''\nlabels: 'type: bug'\nassignees: ''\n\n---\n\n<!---\nThank you for taking the time to report bugs!\n\nWe love code snippets and links to repositories that reproduce the issue, but understand if you don't have the time to add them. We'll do our best with the info you provide, and might ask follow-up questions.\n\nPlease see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.\n--->\n\n**Versions**\n\n- Go:\n- Buildevents:\n\n\n**Steps to reproduce**\n\n1.\n\n**Additional context**\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/feature_request.md",
    "content": "---\nname: Feature request\nabout: Suggest an idea for this project\ntitle: ''\nlabels: 'type: enhancement'\nassignees: ''\n\n---\n\n<!---\nThank you for contributing an idea to this project!\n\nPlease see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.\n--->\n\n**Is your feature request related to a problem? Please describe.**\n\n\n**Describe the solution you'd like**\n\n\n**Describe alternatives you've considered**\n\n\n**Additional context**\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/question-discussion.md",
    "content": "---\nname: Question/Discussion\nabout: General question about how things work or a discussion\ntitle: ''\nlabels: 'type: discussion'\nassignees: ''\n\n---\n\n<!---\nThank you for taking the time to say hello!\n\nPlease see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.\n--->\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/security-vulnerability-report.md",
    "content": "---\nname: Security vulnerability report\nabout: Let us know if you discover a security vulnerability\ntitle: ''\nlabels: 'type: security'\nassignees: ''\n\n---\n\n<!---\nThank you for taking the time to report security vulnerabilities!\n\nPlease see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.\n--->\n**Versions**\n\n- Go:\n- Buildevents:\n\n**Description**\n\n(Please include any relevant CVE advisory links)\n"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "content": "<!--\nThank you for contributing to the project! 💜\nPlease make sure to:\n- Chat with us first if this is a big change\n  - Open a new issue (or comment on an existing one)\n  - We want to make sure you don't spend time implementing something we might have to say No to\n- Add unit tests\n- Mention any relevant issues in the PR description (e.g. \"Fixes #123\")\n\nPlease see our [OSS process document](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md#) to get an idea of how we operate.\n-->\n\n## Which problem is this PR solving?\n\n- Closes #<enter issue here>\n\n## Short description of the changes\n\n## How to verify that this has the expected result\n"
  },
  {
    "path": ".github/dependabot.yml",
    "content": "# To get started with Dependabot version updates, you'll need to specify which\n# package ecosystems to update and where the package manifests are located.\n# Please see the documentation for all configuration options:\n# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates\n\nversion: 2\nupdates:\n  - package-ecosystem: \"gomod\" # See documentation for possible values\n    directory: \"/\" # Location of package manifests\n    schedule:\n      interval: \"monthly\"\n    labels:\n      - \"type: dependencies\"\n    commit-message:\n      prefix: \"maint\"\n      include: \"scope\"\n    groups:\n      examples:\n        patterns:\n          - \"*\"\n"
  },
  {
    "path": ".github/release.yml",
    "content": "# .github/release.yml\n\nchangelog:\n  exclude:\n    labels:\n      - no-changelog\n  categories:\n    - title: 💥 Breaking Changes 💥\n      labels:\n        - \"version: bump major\"\n        - breaking-change\n    - title: 💡 Enhancements\n      labels:\n        - \"type: enhancement\"\n    - title: 🐛 Fixes\n      labels:\n        - \"type: bug\"\n    - title: 🛠 Maintenance\n      labels:\n        - \"type: maintenance\"\n        - \"type: dependencies\"\n        - \"type: documentation\"\n    - title: 🤷 Other Changes\n      labels:\n        - \"*\"\n"
  },
  {
    "path": ".github/workflows/add-to-project-v2.yml",
    "content": "name: Add to project\non:\n  issues:\n    types: [opened]\n  pull_request_target:\n    types: [opened]\njobs:\n  add-to-project:\n    runs-on: ubuntu-latest\n    name: Add issues and PRs to project\n    steps:\n      - uses: actions/add-to-project@main\n        with:\n          project-url: https://github.com/orgs/honeycombio/projects/27\n          github-token: ${{ secrets.GHPROJECTS_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/apply-labels.yml",
    "content": "name: Apply project labels\non: [issues, pull_request_target, label]\njobs:\n  apply-labels:\n    runs-on: ubuntu-latest\n    name: Apply common project labels\n    steps:\n      - uses: honeycombio/oss-management-actions/labels@v1\n        with:\n          github-token: ${{ secrets.GITHUB_TOKEN }}\n"
  },
  {
    "path": ".github/workflows/stale.yml",
    "content": "name: 'Close stale issues and PRs'\non:\n  schedule:\n    - cron: '30 1 * * *'\n\njobs:\n  stale:\n    name: 'Close stale issues and PRs'\n    runs-on: ubuntu-latest\n    permissions:\n      issues: write\n      pull-requests: write\n\n    steps:\n      - uses: actions/stale@v4\n        with:\n          start-date: '2021-09-01T00:00:00Z'\n          stale-issue-message: 'Marking this issue as stale because it has been open 14 days with no activity. Please add a comment if this is still an ongoing issue; otherwise this issue will be automatically closed in 7 days.'\n          stale-pr-message: 'Marking this PR as stale because it has been open 30 days with no activity. Please add a comment if this PR is still relevant; otherwise this PR will be automatically closed in 7 days.'\n          close-issue-message: 'Closing this issue due to inactivity. Please see our [Honeycomb OSS Lifecyle and Practices](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md).'\n          close-pr-message: 'Closing this PR due to inactivity. Please see our [Honeycomb OSS Lifecyle and Practices](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md).'\n          days-before-issue-stale: 14\n          days-before-pr-stale: 30\n          days-before-issue-close: 7\n          days-before-pr-close: 7\n          any-of-labels: 'status: info needed,status: revision needed'\n"
  },
  {
    "path": ".github/workflows/validate-pr-title.yml",
    "content": "name: \"Validate PR Title\"\n\non:\n  pull_request:\n    types:\n      - opened\n      - edited\n      - synchronize\n\njobs:\n  main:\n    name: Validate PR title\n    runs-on: ubuntu-latest\n    steps:\n      - uses: amannn/action-semantic-pull-request@v5\n        id: lint_pr_title\n        name: \"🤖 Check PR title follows conventional commit spec\"\n        env:\n          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}\n        with:\n          # Have to specify all types because `maint` and `rel` aren't defaults\n          types: |\n            maint\n            rel\n            fix\n            feat\n            chore\n            ci\n            docs\n            style\n            refactor\n            perf\n            test\n          ignoreLabels: |\n            \"type: dependencies\"\n      # When the previous steps fails, the workflow would stop. By adding this\n      # condition you can continue the execution with the populated error message.\n      - if: always() && (steps.lint_pr_title.outputs.error_message != null)\n        name: \"📝 Add PR comment about using conventional commit spec\"\n        uses: marocchino/sticky-pull-request-comment@v2\n        with:\n          header: pr-title-lint-error\n          message: |\n            Thank you for contributing to the project! 🎉\n\n            We require pull request titles to follow the [Conventional Commits specification](https://www.conventionalcommits.org/en/v1.0.0/) and it looks like your proposed title needs to be adjusted.\n\n            Make sure to prepend with `feat:`, `fix:`, or another option in the list below.\n\n            Once you update the title, this workflow will re-run automatically and validate the updated title.\n\n            Details:\n\n            ```\n            ${{ steps.lint_pr_title.outputs.error_message }}\n            ```\n\n      # Delete a previous comment when the issue has been resolved\n      - if: ${{ steps.lint_pr_title.outputs.error_message == null }}\n        name: \"❌ Delete PR comment after title has been updated\"\n        uses: marocchino/sticky-pull-request-comment@v2\n        with:\n          header: pr-title-lint-error\n          delete: true\n"
  },
  {
    "path": ".gitignore",
    "content": "# Binaries for programs and plugins\n*.exe\n*.exe~\n*.dll\n*.so\n*.dylib\n\n# Test binary, build with `go test -c`\n*.test\n\n# Output of the go coverage tool, specifically when used with LiteIDE\n*.out\n\nbuildevents\n"
  },
  {
    "path": ".go-version",
    "content": "1.23.2\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# buildevents changelog\n\n## v0.18.0 - 2025-06-30\n\n### Enhancements\n\n- feat: return list of failed jobs in cmd watch (#225) | @cewkrupa\n\n### Maintenance\n\n- maint(deps): bump github.com/honeycombio/beeline-go from 1.18.0 to 1.19.0 in the examples group (#230) | @dependabot\n- maint(deps): bump the examples group across 1 directory with 2 updates (#229) | @dependabot\n- maint(deps): bump the examples group with 3 updates (#227) | @dependabot\n\n## v0.17.0 - 2024-10-16\n\n### Fixes\n\n- fix(watch): not_running is the new queued (#221) | [Liz Fong-Jones](https://github.com/lizthegrey)\n\n### Maintenance\n\n- maint: update go version and docs (#223) | [Jamie Danielson](https://github.com/JamieDanielson)\n- maint(go): update to go1.23 (#222) | [Liz Fong-Jones](https://github.com/lizthegrey)\n- maint(deps): bump the examples group with 3 updates (#218) | [dependabot[bot]](https://github.com/dependabot[bot])\n- docs: update vulnerability reporting process (#219) | [Robb Kidd](https://github.com/robbkidd)\n- maint: update repo for pipeline team ownership (#217) | [Jamie Danielson](https://github.com/JamieDanielson)\n- maint(deps): bump github.com/stretchr/testify from 1.8.4 to 1.9.0 (#214) | [dependabot[bot]](https://github.com/dependabot[bot])\n- maint(deps): bump github.com/honeycombio/beeline-go from 1.14.0 to 1.15.0 (#212) | [dependabot[bot]](https://github.com/dependabot[bot])\n\n## 0.16.0 - 2024-02-29\n\n### Enhancements\n\n- upgrade to libhoney-go 1.21.0 to support classic ingest keys (#208) | [@cewkrupa](https://github.com/cewkrupa)\n\n### Maintenance\n\n- Bump github.com/honeycombio/beeline-go from 1.13.0 to 1.14.0 (#206) | [dependabot](https://github.com/dependabot)\n- Bump github.com/spf13/cobra from 1.7.0 to 1.8.0 (#205) | [dependabot](https://github.com/dependabot)\n- Bump github.com/honeycombio/beeline-go from 1.12.0 to 1.13.0 (#202) | [dependabot](https://github.com/dependabot)\n\n## 0.15.0 - 2023-07-17\n\n### Enhancements\n\n- add `meta.arch` and `meta.os` fields to spans (#200) | [@ismith](https://github.com/ismith)\n\n### Maintenance\n\n- Bump github.com/honeycombio/beeline-go from 1.11.1 to 1.12.0 (#198) | [dependabot](https://github.com/dependabot)\n- Bump github.com/honeycombio/libhoney-go from 1.19.0 to 1.20.0 (#199) | [dependabot](https://github.com/dependabot)\n\n## 0.14.0 - 2023-06-23\n\n### Enhancements\n\n- add support for Windows artifacts (#193) | [@jharley](https://github.com/jharley)\n\n### Maintenance\n\n- Bump Go to 1.20 (#193) | [@jharley](https://github.com/jharley)\n- Bump github.com/spf13/cobra from 1.6.1 to 1.7.0 (#191) | [dependabot](https://github.com/dependabot)\n- Bump github.com/stretchr/testify from 1.8.0 to 1.8.4 (#178, #187, #192) | [dependabot](https://github.com/dependabot)\n- Bump github.com/honeycombio/beeline-go from 1.9.0 to 1.11.1 (#170, #179) | [dependabot](https://github.com/dependabot)\n- Bump github.com/honeycombio/libhoney-go from 1.16.0 to 1.18.0 (#180) | [dependabot](https://github.com/dependabot)\n- Bump github.com/spf13/cobra from 1.5.0 to 1.7.0 (#181, #191) | [dependabot](https://github.com/dependabot)\n\n## 0.13.0 - 2022-08-25\n\n### Enhancements\n\n- include sending error true for spans representing error states for builds (#168) | [@mjayaram](https://github.com/mjayaram)\n- Removes checking and warning for when only the dataset is configured for Buildevents; Updates logic to set default is no Dataset is configured for the non-classic use (#167) | [@mjayaram](https://github.com/mjayaram)\n\n### Maintenance\n\n- Bump github.com/honeycombio/beeline-go from 1.8.0 to 1.9.0 (#166) | [dependabot](https://github.com/dependabot)\n\n## 0.12.1 - 2022-07-20\n\n### Maintenance\n\n- Re-release to fix OpenSSL CVE | [@kentquirk](https://github.com/kentquirk)\n\n## 0.12.0 - 2022-07-14\n\n### Enhancements\n\n- Add support to send data to environments (#162) | [@MikeGoldsmith](https://github.com/MikeGoldsmith)\n\n## 0.11.0 - 2022-07-13\n\n### Enhancements\n\n- add gha-buildevents as GHA provider alias (#160) | [@dstrelau](https://github.com/dstrelau)\n\n### Maintenance\n\n- Bump github.com/spf13/cobra from 1.4.0 to 1.5.0 (#161) | [dependabot](https://github.com/dependabot)\n\n## 0.10.0 - 2022-06-14\n\n### Enhancements\n\n- Build for Darwin ARM64 (#157) | [Kent Quirk](https://github.com/kentquirk) & [John Dorman](https://github.com/boostchicken)\n\n### Maintenance\n\n- [docs] Add examples of generated events (#155) | [Kent Quirk](https://github.com/kentquirk)\n- [docs] Remember to update orb when releasing a new version (#152) | [Vera Reynolds](https://github.com/vreynolds)\n\n## 0.9.2 - 2022-04-25\n\n### Maintenance\n\n- update ci image to cimg/go:1.18 (#150) | [@JamieDanielson](https://github.com/JamieDanielson)\n  - - fixes openSSL CVE\n\n## 0.9.1 - 2022-04-15\n\n- [bug] Fix default value for dataset to be empty so that dataset determination logic works correctly. (#148) [@kentquirk](https://github.com/kentquirk)\n\n## 0.9.0 - 2022-04-14\n\n- Bump cobra to v1.4.0\n- Bump beeline to v1.8.0\n- Bump libhoney to v1.15.8\n- Use cobra.MatchAll instead of identical custom code\n- Clean up buildURL function to construct URLs more safely\n- The `service_name` field is mirrored to `service.name`\n- Detect classic key and change behavior for non-classic mode:\n  - Service Name, if specified, is used as the dataset as well as both `service_name` and `service.name` fields.\n  - If dataset is specified and service name is not, it will be used but will generate a warning (except in quiet mode).\n  - If both are specified, service name will be used, dataset is ignored, and a warning will be emitted (except in quiet mode).\n  - The command name is now sent as command_name (in classic it is still sent as service_name).\n  - The `watch` command now sets the `name` field to merely `watch` rather than a high-cardinality value, making it easier to aggregate queries across different builds.\n  - Dataset name is trimmed of leading/trailing whitespace; if any was found emits a warning (except in quiet mode)\n\n## 0.8.0 - 2022-01-13\n\n### Fixes\n\n- Return underlying exit code when running commands (#137) | [@jhchabran](https://github.com/jhchabran)\n\n## 0.7.2 - 2022-01-07\n\n### Fixes\n\n- Display underlying error when verifying API key (#135) | [@jhchabran](https://github.com/jhchabran)\n\n### Maintenance\n\n- Update ci image (#132) | [@vreynolds](https://github.com/vreynolds)\n- Add re-triage workflow (#131) | [@vreynolds](https://github.com/vreynolds)\n- Only create one draft gh release (#128) | [@vreynolds](https://github.com/vreynolds)\n- Bump github.com/spf13/cobra from 0.0.7 to 1.2.1 (#130)\n- Bump github.com/honeycombio/beeline-go from 1.3.1 to 1.3.2 (#129)\n- Bump github.com/honeycombio/beeline-go from 1.2.0 to 1.3.1 (#123)\n\n## 0.7.1 - 2021-11-19\n\n### Fixed\n\n- Do not fail the build if `watch` fails to fetch Honeycomb URL (#126) | [@asdvalenzuela](https://github.com/asdvalenzuela)\n\n### Maintenance\n\n- Create draft gh release during publish (#124) | [@MikeGoldsmith](https://github.com/MikeGoldsmith)\n\n## 0.7.0 - 2021-11-03\n\n### Added\n\n- Allow specifying an alternative shell (#119) | [@estheruary](https://github.com/estheruary)\n\n### Maintenance\n\n- empower apply-labels action to apply labels (#120)\n- bump libhoney-go to v1.15.6 (#121)\n- Bump github.com/honeycombio/libhoney-go from 1.15.4 to 1.15.5 (#118)\n- Change maintenance badge to maintained (#116)\n- Adds Stalebot (#117)\n- Add NOTICE (#113)\n- Bump github.com/honeycombio/beeline-go from 1.1.2 to 1.2.0 (#109)\n- Bump github.com/honeycombio/libhoney-go from 1.15.3 to 1.15.4 (#108)\n- Add issue and PR templates (#112)\n- Add OSS lifecycle badge (#111)\n- Add community health files (#110)\n\n## 0.6.0 - 2021-07-14\n\n### Added\n\n- Forward stdin. [#99](https://github.com/honeycombio/buildevents/pull/99) | [@shlevy](https://github.com/shlevy)\n\n### Maintenance\n\n- Bump github.com/spf13/cobra from 0.0.5 to 0.0.7 [#102](https://github.com/honeycombio/buildevents/pull/102)\n- Bump github.com/honeycombio/libhoney-go from 1.10.0 to 1.15.3 [#101](https://github.com/honeycombio/buildevents/pull/101)\n- Bump github.com/jszwedko/go-circleci from 0.2.0 to 0.3.0 [#103](https://github.com/honeycombio/buildevents/pull/103)\n- stop watching dependabot builds [#106](https://github.com/honeycombio/buildevents/pull/106)\n\n## 0.5.2 - 2021-07-08\n\n### Added\n\n- Add support for Buildkite CI environment detection. [#97](https://github.com/honeycombio/buildevents/pull/97) | [@MikeGoldsmith](https://github.com/MikeGoldsmith)\n\n## 0.5.1 - 2021-03-27\n\n### Added\n\n- Added ARM64 builds. [#91](https://github.com/honeycombio/buildevents/pull/91) | [@ismith](https://github.com/ismith)\n\n## 0.5.0 - 2021-02-09\n\n### Added\n\n- Quiet option to cmd [#80](https://github.com/honeycombio/buildevents/pull/80) | [@tybritten](https://github.com/tybritten)\n- Bitbucket support [#85](https://github.com/honeycombio/buildevents/pull/85) | [@manjunathb4461](https://github.com/manjunathb4461)\n- Support for overriding default event fields [#76](https://github.com/honeycombio/buildevents/pull/76) | [@MarilynFranklin](https://github.com/MarilynFranklin)\n\n### Fixed\n\n- Azure pipelines constant typo [#84](https://github.com/honeycombio/buildevents/pull/84) | [@manjunathb4461](https://github.com/manjunathb4461)\n"
  },
  {
    "path": "CODE_OF_CONDUCT.md",
    "content": "# Code of Conduct\n\nThis project has adopted the Honeycomb User Community Code of Conduct to clarify expected behavior in our community.\n\nhttps://www.honeycomb.io/honeycomb-user-community-code-of-conduct/"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing Guide\n\nPlease see our [general guide for OSS lifecycle and practices.](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md)\n"
  },
  {
    "path": "LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "LICENSES/github.com/facebookgo/clock/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2014 Ben Johnson\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "LICENSES/github.com/facebookgo/limitgroup/license",
    "content": "BSD License\n\nFor limitgroup software\n\nCopyright (c) 2015, Facebook, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n * Neither the name Facebook nor the names of its contributors may be used to\n   endorse or promote products derived from this software without specific\n   prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "LICENSES/github.com/facebookgo/muster/license",
    "content": "BSD License\n\nFor muster software\n\nCopyright (c) 2015, Facebook, Inc. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without modification,\nare permitted provided that the following conditions are met:\n\n * Redistributions of source code must retain the above copyright notice, this\n   list of conditions and the following disclaimer.\n\n * Redistributions in binary form must reproduce the above copyright notice,\n   this list of conditions and the following disclaimer in the documentation\n   and/or other materials provided with the distribution.\n\n * Neither the name Facebook nor the names of its contributors may be used to\n   endorse or promote products derived from this software without specific\n   prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND\nANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\nWARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE\nDISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR\nANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\n(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON\nANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\nSOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "LICENSES/github.com/honeycombio/beeline-go/propagation/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "LICENSES/github.com/honeycombio/beeline-go/propagation/NOTICE",
    "content": "Copyright (c) 2016-Present Honeycomb, Hound Technology, Inc. All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "LICENSES/github.com/honeycombio/libhoney-go/LICENSE",
    "content": "                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"{}\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright {yyyy} {name of copyright owner}\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "LICENSES/github.com/honeycombio/libhoney-go/NOTICE",
    "content": "Copyright (c) 2016-Present Honeycomb, Hound Technology, Inc. All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "LICENSES/github.com/jszwedko/go-circleci/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Jesse Szwedko\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "LICENSES/github.com/klauspost/compress/LICENSE",
    "content": "Copyright (c) 2012 The Go Authors. All rights reserved.\nCopyright (c) 2019 Klaus Post. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n------------------\n\nFiles: gzhttp/*\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2016-2017 The New York Times Company\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n\n------------------\n\nFiles: s2/cmd/internal/readahead/*\n\nThe MIT License (MIT)\n\nCopyright (c) 2015 Klaus Post\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n---------------------\nFiles: snappy/*\nFiles: internal/snapref/*\n\nCopyright (c) 2011 The Snappy-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n-----------------\n\nFiles: s2/cmd/internal/filepathx/*\n\nCopyright 2016 The filepathx Authors\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.\n"
  },
  {
    "path": "LICENSES/github.com/klauspost/compress/internal/snapref/LICENSE",
    "content": "Copyright (c) 2011 The Snappy-Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "LICENSES/github.com/klauspost/compress/zstd/internal/xxhash/LICENSE.txt",
    "content": "Copyright (c) 2016 Caleb Spare\n\nMIT License\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "LICENSES/github.com/kr/logfmt/Readme",
    "content": "Go package for parsing (and, eventually, generating)\nlog lines in the logfmt style.\n\nSee http://godoc.org/github.com/kr/logfmt for format, and other documentation and examples.\n\nCopyright (C) 2013 Keith Rarick, Blake Mizerany\n\nPermission 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:\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE 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.\n"
  },
  {
    "path": "LICENSES/github.com/spf13/cobra/LICENSE.txt",
    "content": "                                Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n"
  },
  {
    "path": "LICENSES/github.com/spf13/pflag/LICENSE",
    "content": "Copyright (c) 2012 Alex Ogier. All rights reserved.\nCopyright (c) 2012 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n   * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "LICENSES/github.com/vmihailenco/msgpack/v5/LICENSE",
    "content": "Copyright (c) 2013 The github.com/vmihailenco/msgpack Authors.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "LICENSES/github.com/vmihailenco/tagparser/v2/LICENSE",
    "content": "Copyright (c) 2019 The github.com/vmihailenco/tagparser Authors.\nAll rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n   * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n   * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "LICENSES/gopkg.in/alexcesaro/statsd.v2/LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Alexandre Cesaro\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of\nthe Software, and to permit persons to whom the Software is furnished to do so,\nsubject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS\nFOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR\nCOPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER\nIN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\nCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "Makefile",
    "content": "MAKEFLAGS += --warn-undefined-variables\nMAKEFLAGS += --no-builtin-rules\nMAKEFLAGS += --no-builtin-variables\n\nGOTESTCMD = $(if $(shell command -v gotestsum),gotestsum --junitfile ./test_results/$(1).xml --format testname --,go test)\n\n.PHONY: test\n#: run all tests\ntest: test_with_race test_all\n\n.PHONY: test_with_race\n#: run only tests tagged with potential race conditions\ntest_with_race: test_results\n\t@echo\n\t@echo \"+++ testing - race conditions?\"\n\t@echo\n\t$(call GOTESTCMD,$@) -tags race --race --timeout 60s -v ./...\n\n.PHONY: test_all\n#: run all tests, but with no race condition detection\ntest_all: test_results\n\t@echo\n\t@echo \"+++ testing - all the tests\"\n\t@echo\n\t$(call GOTESTCMD,$@) -tags all --timeout 60s -v ./...\n\ntest_results:\n\t@mkdir -p test_results\n\n.PHONY: install-tools\ninstall-tools:\n\tgo install github.com/google/go-licenses/v2@v2.0.0-alpha.1\n\n.PHONY: update-licenses\nupdate-licenses: install-tools\n\trm -rf LICENSES; \\\n\t#: We ignore the standard library (go list std) as a workaround for \\\n\t\"https://github.com/google/go-licenses/issues/244.\" The awk script converts the output \\\n  of `go list std` (line separated modules) to the input that `--ignore` expects (comma separated modules).\n\tgo-licenses save --save_path LICENSES --ignore \"github.com/honeycombio/buildevents\" \\\n\t\t--ignore $(shell go list std | awk 'NR > 1 { printf(\",\") } { printf(\"%s\",$$0) } END { print \"\" }') ./;\n\n\n.PHONY: verify-licenses\nverify-licenses: install-tools\n\tgo-licenses save --save_path temp --ignore \"github.com/honeycombio/buildevents\" \\\n\t\t--ignore $(shell go list std | awk 'NR > 1 { printf(\",\") } { printf(\"%s\",$$0) } END { print \"\" }') ./; \\\n\tchmod +r temp; \\\n    if diff temp LICENSES; then \\\n      echo \"Passed\"; \\\n      rm -rf temp; \\\n    else \\\n      echo \"LICENSES directory must be updated. Run make update-licenses\"; \\\n      rm -rf temp; \\\n      exit 1; \\\n    fi; \\\n"
  },
  {
    "path": "NOTICE",
    "content": "Copyright (c) 2016-Present Honeycomb, Hound Technology, Inc. All Rights Reserved.\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n   http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n"
  },
  {
    "path": "OSSMETADATA",
    "content": "osslifecycle=maintained\n"
  },
  {
    "path": "README.md",
    "content": "# buildevents\n\n[![OSS Lifecycle](https://img.shields.io/osslifecycle/honeycombio/buildevents?color=success)](https://github.com/honeycombio/home/blob/main/honeycomb-oss-lifecycle-and-practices.md)\n[![CircleCI](https://circleci.com/gh/honeycombio/buildevents.svg?style=shield)](https://circleci.com/gh/honeycombio/buildevents)\n\nbuildevents is a small binary used to help instrument builds in a build system such as Travis-CI, CircleCI, Jenkins, and so on. It is installed during the setup phase and then invoked as part of each step in order to visualize the build as a trace in Honeycomb\n\nThe trace that you get at the end represents the entire build. It has spans for each section and subsection of the build, representing groups of actual commands that are run. The duration of each span is how long that stage or specific command took to run, and includes whether or not the command succeeded.\n\nHere's an example showing a build that ran on CircleCI. It goes through running go tests, setting up javascript dependencies, triggers js_build and poodle_test in parallel after dependencies are configured, and then continues off below the captured portion of the waterfall.\n\n![CircleCI_Build_Trace](https://user-images.githubusercontent.com/361454/57872910-ac9eea00-77c1-11e9-8bdd-db7a870dcd61.png)\n\n# Setup\n\nGetting your build ready to use `buildevents` involves:\n* installing the `buildevents` binary in your build environment\n* setting a number of environment variables for configuring the tool\n* choosing a unique trace identifier\n\n## Installation\n\nIf you have a working go environment in your build, the easiest way to install `buildevents` is via `go get`.\n\n```\ngo get github.com/honeycombio/buildevents/\n```\n\nThere are also built binaries for linux and macOS hosted on Github and available under the [releases](https://github.com/honeycombio/buildevents/releases) tab. The following commands will download and make executable the github-hosted binary.\n\n**linux, 32-bit x86:**\n\n```\ncurl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-386\nchmod 755 buildevents\n```\n\n**linux, 64-bit x86:**\n\n```\ncurl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64\nchmod 755 buildevents\n```\n\n**linux, arm64:**\n\n```\ncurl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-arm64\nchmod 755 buildevents\n```\n\n**macOS, amd64:**\n\n```\ncurl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-darwin-amd64\nchmod 755 buildevents\n```\n\n**macOS, arm64:**\n\n```\ncurl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-darwin-arm64\nchmod 755 buildevents\n```\n\n**windows, 32-bit x86:**\n\n```\ncurl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-386.exe\n```\n\n**windows, 64-bit x86:**\n\n```\ncurl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-amd64.exe\n```\n\n**windows, arm64:**\n\n```\ncurl.exe -L -o buildevents.exe https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-windows-arm64.exe\n```\n\nIf this doesn't work for you, please [let us know](mailto:support@honeycomb.io) - we'd love to hear what would work.\n\n<!-- TODO provide a compiled binary at some evergreen 'latest' URL  -->\n\n## Environment Variables\n\nThere is one required environment variable; it will hold your Honeycomb API key (available at https://ui.honeycomb.io/account). If it is absent, events will not be sent to Honeycomb. Set `BUILDEVENT_APIKEY` to hold your API key.\n\nThere are several other optional enviornment variables that will adjust the behavior of `buildevents`:\n\n* `BUILDEVENT_DATASET` sets the Honeycomb dataset to use. The default is `buildevents`\n* `BUILDEVENT_APIHOST` sets the API target for sending Honeycomb traces.  Default is `https://api.honeycomb.io/`\n* `BUILDEVENT_CIPROVIDER` if set, a field in all spans named `ci_provider` will contain this value. If unset, `buildevents` will inspect the environment to try and detect Travis-CI, CircleCI, GitLab-CI, Buildkite, Jenkins-X, Google-Cloud-Build and Bitbucket-Pipelines (by looking for the environment variables `TRAVIS`, `CIRCLECI`, `BUILDKITE`, `GITLAB_CI`, `JENKINS-X`, `GOOGLE-CLOUD-BUILD` and `BITBUCKET_BUILD_NUMBER` respectively). If either Travis-CI, CircleCI, GitLab-CI, Buildkite, Jenkins-X, Google-Cloud-Build or Bitbucket-Pipelines are detected, `buildevents` will add a number of additional fields from the environment, such as the branch name, the repository, the build number, and so on. If detection fails and you are on Travis-CI, CircleCI, GitLab-CI, Jenkins-X, Google-Cloud-Build or Bitbucket-Pipelines setting this to `Travis-CI`, `CircleCI`, `Buildkite`, `GitLab-CI`, `Jenkins-X`, `Google-Cloud-Build`, or `Bitbucket-Pipelines` precisely will also trigger the automatic field additions.\n* `BUILDEVENT_FILE` if set, is used as the path of a text file holding arbitrary key=val pairs (multi-line-capable, logfmt style) that will be added to the Honeycomb event.\n\n## Trace Identifier\n\nThe `buildevents` script needs a unique ID to join together all of the steps and commands with the build.  This is the Trace ID. It must be unique within the Honeycomb dataset holding traces. An excellent choice is the Build ID, since it is both unique (even when re-running builds, you will often get a new Build ID) and is also a primary value that the build system uses to identify the build.\n\nThe Build ID may already be available in the environment for your build:\n* Travis-CI: `TRAVIS_BUILD_ID`\n* CircleCI: `CIRCLE_WORKFLOW_ID` (if you're using workflows)\n* CircleCI: `CIRCLE_BUILD_NUM` (the build number for this job if you're not using workflows)\n* GitLab-CI: `CI_PIPELINE_ID`\n* Buildkite: `BUILDKITE_BUILD_ID`\n* JenkinsX: `JENKINSX_BUILD_NUMBER`\n* Google-Cloud-Build: `BUILD_ID`\n* GitHub Actions: `GITHUB_RUN_ID`\n* Bitbucket Pipelines: `BITBUCKET_BUILD_NUMBER`\n\n# Use\n\nNow that `buildevents` is installed and configured, actually generating spans to send to Honeycomb involves invoking `buildevents` in various places throughout your build config.\n\n`buildevents` is invoked with one of three modes, `build`, `step`, and `cmd`.\n* The `build` mode sends the root span for the entire build. It should be called when the build finishes and records the duration of the entire build. It emits a URL pointing to the generated trace in Honeycomb to STDOUT.\n* The `step` mode represents a block of related commands. In Travis-CI, this is one of `install`, `before_script`, `script`, and so on. In CircleCI, this most closely maps to a single job. It should be run at the end of the step.\n* The `cmd` mode invokes an individual command that is part of the build, such as running DB migrations or running a specific test suite. It must be able to be expressed as a single shell command - either a process like `go test` or a shell script. The command to run is the final argument to `buildevents` and will be launched via `bash -c` using `exec`. You can specify an alternate shell using the `-s/--shell` flag but it must support the the `-c` flag.\n\n## build\n\nThough listed first, running `buildevents` in `build` mode should actually be the last command that your build runs so that it can record the total running duration for the build. It does this by having the time the build started as one of the arguments passed in.\n\nThe output of buildevents in `build` will be a link to the trace within Honeycomb. Take this URL and use it in the notifications your CI system emits to easily jump to the Honeycomb trace for a build. If the API Key used in this run is not valid, no output will be emitted.\n\nNote that CircleCI uses an alternate method of creating the root span, so the `build` command should not be used. Use the `watch` command instead.\n\nFor the `build` step, you must first record the time the build started.\n* Travis-CI: the `env` section of the config file establishes some global variables in the environment. This is run before anything else, so gets a good start time.\n\nThe actual invocation of `buildevents build` should be as close to the last thing that the build does as possible.\n* Travis-CI: the end of the `after_failure` and `after_success` steps\n\nTravis-CI example:\n```yaml\nenv:\n  global:\n    - BUILD_START=$(date +%s)\n\n...\n\nafter_failure:\n  - traceURL=$(buildevents build $TRAVIS_BUILD_ID $BUILD_START failure)\n  - echo \"Honeycomb Trace: $traceURL\"\nafter_success:\n  - traceURL=$(buildevents build $TRAVIS_BUILD_ID $BUILD_START success)\n  - echo \"Honeycomb Trace: $traceURL\"\n```\n\n### what it generates\n\nGiven this command:\n\n```bash\nbuildevents $HOST -k $API_KEY build htjebmye $BUILD_STARTTIME success\n```\n\nThe event that arrives at Honeycomb (which has no trace.parent_id since it is the root of a trace) might look like:\n\n```json\n{\n    \"Timestamp\": \"2022-05-24T01:49:13Z\",\n    \"command_name\": \"build\",\n    \"duration_ms\": 4981,\n    \"meta.version\": \"dev\",\n    \"name\": \"build htjebmye\",\n    \"service.name\": \"build\",\n    \"service_name\": \"build\",\n    \"source\": \"buildevents\",\n    \"status\": \"success\",\n    \"trace.span_id\": \"htjebmye\",\n    \"trace.trace_id\": \"htjebmye\"\n}\n```\n\n## watch\n\nCirclecI requires use of the CircleCI API to detect when workflows start and stop. There is no facility to always run a job after all others, so what works using the Travis-CI `after_failure` will not work on CircleCI. However, the CircleCI API exposes when the current workflow has started, and can be used intsead.\n\nThe `watch` command polls the CircleCI API and waits until all jobs have finished (either succeeded, failed, or are blocked). It then reports the final status of the build with the appropriate timers.  `watch` should be invoked in a job all on its own, dependent on only the `setup` job, with only the Trace ID to use. After some time, `watch` will timeout waiting for the build to finish and fail. The timeout default is 10 minutes and can be overridden by setting `BUILDEVENT_TIMEOUT`\n\nUsing the `watch` command requires a personal (not project) CircleCI API token. You can provide this token to `buildevents` via the `BUILDEVENT_CIRCLE_API_TOKEN` environment variable. You can get a personal API token from https://circleci.com/account/api. For more detail on tokens, please see the [CircleCI API Tokens documentation](https://circleci.com/docs/2.0/managing-api-tokens/)\n\nThe `watch` command will emit a link to the finished trace to the job output in Honeycomb when the build is complete.\n\n```yaml\njobs:\n  send_trace:\n    steps:\n      - run: buildevents watch $CIRCLE_WORKFLOW_ID\n```\n\n## step\n\nThe `step` mode is the outer wrapper that joins a collection of individual `cmd`s together in to a block. Like the `build` command, it should be run at the end of the collection of `cmd`s and needs a start time collected at the beginning. In addition to the trace identifier, it needs a step identifier that will also be passed to all the `cmd`s that are part of this step in order to tie them together in to a block. Because the step identifier must be available to all commands, both it and the start time should be generated at the beginning of the step and recorded. The step identifier must be unique within the trace (but does not need to be globally unique). To avoid being distracting, we use a hash of the step name as the identifier.\n\nTravis-CI exmaple:\n```yaml\nbefore_script:\n  - STEP_START=$(date +%s)\n  - STEP_SPAN_ID=$(echo before_script | sum | cut -f 1 -d \\ )\n  - ... do stuff\n  - buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START before_script\n```\n\nCircleCI example:\n```yaml\njobs:\n  go_test:\n    steps:\n      - run: echo \"STEP_START=$(date +%s)\" >> $BASH_ENV\n      - run: echo \"STEP_SPAN_ID=$(echo go_test | sum | cut -f 1 -d \\ )\" >> $BASH_ENV\n      - run: ... do stuff\n      - run:\n          name: finishing span for the job\n          command: $GOPATH/bin/buildevents step $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID $STEP_START go_test\n          when: always   # ensures the span is always sent, even when something in the job fails\n```\n\n### what it generates\n\nGiven this command:\n\n```bash\nbuildevents $HOST -k $API_KEY step htjebmye building_htjebmye $STEP_STARTTIME building\n```\n\nThe event that arrives at Honeycomb might look like:\n\n```json\n{\n    \"Timestamp\": \"2022-05-24T01:49:14Z\",\n    \"command_name\": \"step\",\n    \"duration_ms\": 3064,\n    \"meta.version\": \"dev\",\n    \"name\": \"building\",\n    \"service.name\": \"step\",\n    \"service_name\": \"step\",\n    \"source\": \"buildevents\",\n    \"trace.parent_id\": \"htjebmye\",\n    \"trace.span_id\": \"building_htjebmye\",\n    \"trace.trace_id\": \"htjebmye\"\n}\n```\n\n## cmd\n\nRunning `buildevents cmd` will run the given command, time it, and include the `status` of the command (`success` or `failure`). `buildevents` passes through both STDOUT and STDERR from the process it wraps, and exits with the same exit code as the wrapped process. The actual command to run is separated from the `buildevents` arguments by a double hyphen `--`.\n\nThis is the most frequent line you'll see in your config file; anything of consequence should generate a span.\n\nTravis-CI example:\n```yaml\nscript:\n  - buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-test -- go test -timeout 2m -mod vendor ./...\n```\n\nCircleCI example:\n```yaml\njobs:\n  go_test:\n    steps:\n      - run: $GOPATH/bin/buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-test -- go test -timeout 2m -mod vendor ./...\n```\n\n### what it generates\n\nGiven this command:\n\n```bash\nbuildevents $HOST -k $API_KEY cmd htjebmye building_htjebmye compile -- sleep 1\n```\n\nThe event that arrives at Honeycomb might look like:\n\n```json\n{\n    \"Timestamp\": \"2022-05-24T01:49:14.653182Z\",\n    \"cmd\": \"\\\"sleep\\\" \\\"1\\\"\",\n    \"command_name\": \"cmd\",\n    \"duration_ms\": 1008,\n    \"meta.version\": \"dev\",\n    \"name\": \"compile\",\n    \"service.name\": \"cmd\",\n    \"service_name\": \"cmd\",\n    \"source\": \"buildevents\",\n    \"status\": \"success\",\n    \"trace.parent_id\": \"building_htjebmye\",\n    \"trace.span_id\": \"6facde6ac6a95e704b9ec1c837270578\",\n    \"trace.trace_id\": \"htjebmye\"\n}\n```\n\n## Attaching more traces from your build and test process\n\nEvery command running through `buildevents cmd` will receive a `HONEYCOMB_TRACE` environment variable that contains a marshalled trace propagation context. This can be used to connect more spans to this trace.\n\nRuby Beeline example:\n```ruby\n# at the very start of the command\n# establish a command-level span, linking to the buildevent\nprocess_span = Honeycomb.start_span(name: File.basename($PROGRAM_NAME), serialized_trace: ENV['HONEYCOMB_TRACE'])\nHoneycomb.add_field_to_trace('process.full_name', $PROGRAM_NAME)\n\n# if you're not passing sensitive information through CLI args, enable this for more insights.\n#Honeycomb.add_field_to_trace('process.args', ARGV)\n\n# override the HONEYCOMB_TRACE for sub-processes\nENV['HONEYCOMB_TRACE'] = process_span.to_trace_header\n\n# ensure that the process_span is sent before the process terminates\nat_exit do\n  if $ERROR_INFO&.is_a?(SystemExit)\n    process_span.add_field('process.exit_code', $ERROR_INFO.status)\n  elsif $ERROR_INFO\n    process_span.add_field('process.exit_code', $ERROR_INFO.class.name)\n  else\n    process_span.add_field('process.exit_code', 'unknown')\n  end\n  process_span.send\nend\n```\n\n# Putting it all together\n\nWe've covered each of the three modes in which `buildevents` is invoked and shown abbreviated examples for each one. Now it's time to look at an entire config to see how they interact: installation, running a build, and finally reporting the whole thing.\n\nIn both of these examples, the `BUILDEVENT_APIKEY` should be set in the protected environment variable section of the CI config so that your API key is not checked in to your source.\n\nTravis-CI example:\n```yaml\nenv:\n  global:\n    - BUILD_START=$(date +%s)\n\ninstall:\n  - STEP_START=$(date +%s)\n  - STEP_SPAN_ID=$(echo install | sum | cut -f 1 -d \\ )\n  - curl -L -o buildevents https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64\n  - chmod 755 buildevents\n  - # ... any other setup necessary for your build\n  - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START install\n\nscript:\n  - STEP_START=$(date +%s)\n  - STEP_SPAN_ID=$(echo script | sum | cut -f 1 -d \\ )\n  - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID go-tests -- go test ./...\n  - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID js-tests -- yarn test\n  - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START script\n\nafter_failure:\n  - ./buildevents build $TRAVIS_BUILD_ID $BUILD_START failure\n\nafter_success:\n  - STEP_START=$(date +%s)\n  - STEP_SPAN_ID=$(echo after_success | sum | cut -f 1 -d \\ )\n  - ./buildevents cmd $TRAVIS_BUILD_ID $STEP_SPAN_ID build -- go install ./...\n  - # ... tar up artifacts, upload them, etc.\n  - ./buildevents step $TRAVIS_BUILD_ID $STEP_SPAN_ID $STEP_START after_success\n  - ./buildevents build $TRAVIS_BUILD_ID $BUILD_START success\n```\n\nCircleCI example:\n```yaml\nversion: 2.1\n\n# factored out start/finish_job_span commands here so we don't have every one of our build jobs duplicating them\ncommands:\n  with_job_span:\n    parameters:\n      steps:\n        type: steps\n    steps:\n      - attach_workspace:\n          at: buildevents\n      - run:\n          name: starting span for job\n          command: |\n            echo \"STEP_START=$(date +%s)\" >> $BASH_ENV\n            echo \"STEP_SPAN_ID=$(echo $CIRCLE_JOB | sum | cut -f 1 -d \\ )\" >> $BASH_ENV\n      - run: echo \"PATH=$PATH:buildevents/bin/\" >> $BASH_ENV\n      - steps: << parameters.steps >>\n      - run:\n          name: finishing span for job\n          command: buildevents step $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID $STEP_START $CIRCLE_JOB\n          when: always\n\njobs:\n  setup:\n    steps:\n      - run: |\n          mkdir -p buildevents/bin\n          date +%s > buildevents/build_start\n      - run: go get github.com/honeycombio/buildevents\n      - run: cp $GOPATH/bin/buildevents buildevents/bin/\n      - persist_to_workspace:\n          root: buildevents\n          paths:\n            - build_start\n            - bin/buildevents\n  send_trace:\n    steps:\n      - attach_workspace:\n          at: buildevents\n      - run: buildevents watch $CIRCLE_WORKFLOW_ID\n  test:\n    steps:\n      - with_job_span:\n          steps:\n            - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID go-tests -- go test ./...\n            - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID js-tests -- yarn test\n  build:\n    steps:\n      - with_job_span:\n          steps:\n            - run: mkdir artifacts\n            - run: buildevents cmd $CIRCLE_WORKFLOW_ID $STEP_SPAN_ID build -- go install ./...\n            - run: # publish your build artifacts\n\nworkflows:\n  test-and-build:\n    jobs:\n      - setup\n      - send_trace:\n          requires:\n            - setup\n      - test:\n          requires:\n            - setup\n      - build:\n          requires:\n            - test\n```\n\nGitLab CI example:\n```yaml\n# Not a huge fan of YAML anchors, but it's the easiest way to\n# extend the scripts in jobs where you need other before_script and after_script\n.default_before_script: &default_before_script\n  - STEP_START=$(date +%s)\n  - STEP_SPAN_ID=$(echo $CI_JOB_NAME | sum | cut -f 1 -d \\ )\n  - echo \"export STEP_START=$STEP_START\" >> buildevents/env\n  - echo \"export STEP_SPAN_ID=$STEP_SPAN_ID\" >> buildevents/env\n  - echo \"export PATH=\\\"$PATH:buildevents/bin/\\\"\" >> buildevents/env\n  - source buildevents/env\n  - cat buildevents/env\n\n.default_after_script: &default_after_script\n  - source buildevents/env\n  - cat buildevents/env\n  - buildevents step $CI_PIPELINE_ID $STEP_SPAN_ID $STEP_START $CI_JOB_NAME\n\ndefault:\n  image: golang:latest\n  before_script:\n    - *default_before_script\n  after_script:\n    - *default_after_script\n\nstages:\n  # .pre and .post are guaranteed to be first and last run jobs\n  # https://docs.gitlab.com/ee/ci/yaml/README.html#pre-and-post\n  - .pre\n  - build\n  - test\n  - .post\n\nsetup:\n  before_script:\n    - mkdir -p buildevents/bin/\n    - *default_before_script\n  script:\n    - curl -L -o main https://github.com/honeycombio/buildevents/releases/latest/download/buildevents-linux-amd64\n    - chmod 755 main\n    - mv main buildevents/bin/buildevents\n    - export BUILD_START=$(date +%s)\n    - echo \"export BUILD_START=$(date +%s)\" >> buildevents/env\n  artifacts:\n    paths:\n      - buildevents\n  stage: .pre\n\ngo_build:\n  script:\n    - buildevents cmd $CI_PIPELINE_ID $STEP_SPAN_ID build -- go install ./...\n  stage: build\n\ngo_test:\n  script:\n    - buildevents cmd $CI_PIPELINE_ID $STEP_SPAN_ID build -- go test ./...\n  stage: test\n\nsend_success_trace:\n  script:\n    - \"traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START success)\"\n    - \"echo \\\"Honeycomb Trace: $traceURL\\\"\"\n  stage: .post\n  rules:\n    - when: on_success\n\nsend_failure_trace:\n  script:\n    - \"traceURL=$(buildevents build $CI_PIPELINE_ID $BUILD_START failure)\"\n    - \"echo \\\"Honeycomb Trace: $traceURL\\\"\"\n  stage: .post\n  rules:\n    - when: on_failure\n```\n\n# Positional argument reference\n\nAll the arguments to the various `buildevents` modes are listed above, but for\nconvenience, here is a summary of the modes and the arguments that each\nrequires.\n\nThe first argument is the running mode for this invocation of buildevents:\n`build`, `watch`, `step`, or `cmd` The remaining arguments differ depending on the\nmode.\n\narguments for the `build` mode:\n1. `build_id` this is used as both the trace ID and to generate a URL to link back to the build\n2. `start_time` used to calculate the total duration of the build\n3. `status` should be `success` or `failure` and indicates whether the overall build succeeeded or failed\n\narguments for the `watch` mode:\n1. `build_id` this is used as the trace ID\n\narguments for the `step` mode:\n1. `build_id` this is used as both the trace ID and to generate a URL to link back to the build\n1. `step_id` buildevents expects a build to contain steps, and each step to have commands. The step ID is used to help construct this tree\n1. `start_time` used to calculate the total duration of running this step in the build\n1. `name` the last argument is the name for this step or command, used in the Honeycomb UI\n\narguments for the `cmd` mode:\n1. `build_id` this is used as both the trace ID and to generate a URL to link back to the build\n1. `step_id` buildevents expects a build to contain steps, and each step to have commands. The step ID is used to help construct this tree\n1. `name` the name for this command, used in the Honeycomb UI\n1. `--` double hyphen indicates the rest of the line will be the command to run\n\n## Note\n`name` is most useful if it is a low-cardinality value, usually something like the name of a step in your process. Using a low-cardinality value makes it valuable to do things like `GROUP BY name` in your queries.\n\n## Differences between Classic and non-Classic environments\n\nFor \"Honeycomb Classic\", `buildevents` works almost the same as it always has. It has added service.name in addition to service_name; both fields have the same value.\n\nIn a non-Classic environment, there are several differences:\n* Service Name, if specified, is used as the dataset as well as both `service_name` and `service.name` fields.\n* if dataset is specified and service name is not, it will be used but will generate a warning.\n* if both are specified, service name will be used, dataset is ignored, and a warning will be emitted (except in quiet mode)\n* the command name is now sent as command_name (in classic it is sent as service_name)\n* the watch command now sets the `name` field to merely `watch` rather than a high-cardinality value, making it easier to aggregate queries across different builds\n\n"
  },
  {
    "path": "RELEASING.md",
    "content": "# Releasing\n\n- Check that licenses are current with `make verify-licenses`\n  - If there are any changes, submit a separate PR to update licenses using `make update-licenses`.\n- Prep update PR for the [orb](https://github.com/honeycombio/buildevents-orb) with the new version of buildevents.\n- Update `CHANGELOG.md` with the changes since the last release.\n  - Use below command to get a list of all commits since last release\n\n    ```sh\n    git log <last-release-tag>..HEAD --pretty='%Creset- %s | [%an](https://github.com/%an)'\n    ```\n\n  - Copy the output from the command above into the top of [changelog](./CHANGELOG.md)\n  - fix each `https://github.com/<author-name>` to point to the correct github username\n  (the `git log` command can't do this automatically)\n  - organize each commit based on their prefix into below three categories:\n\n    ```sh\n    ### Features\n      - <a-commit-with-feat-prefix>\n\n    ### Fixes\n      - <a-commit-with-fix-prefix>\n\n    ### Maintenance\n      - <a-commit-with-maintenance-prefix>\n    ```\n\n- Commit changes, push, and open a release preparation pull request for review.\n- Once the pull request is merged, fetch the updated `main` branch.\n- Apply a tag for the new version on the merged commit (e.g. `git tag -a v2.3.1 -m \"v2.3.1\"`)\n- Push the tag upstream (this will kick off the release pipeline in CI) e.g. `git push origin v2.3.1`\n- Ensure that there is a draft GitHub release created as part of CI publish steps.\n- Click \"generate release notes\" in GitHub for full changelog notes and any new contributors.\n"
  },
  {
    "path": "SECURITY.md",
    "content": "# Security Policy\n\nThis security policy applies to public projects under the [honeycombio organization][gh-organization] on GitHub.\nFor security reports involving the services provided at `(ui|ui-eu|api|api-eu).honeycomb.io`, refer to the [Honeycomb Bug Bounty Program][bugbounty] for scope, expectations, and reporting procedures.\n\n## Security/Bugfix Versions\n\nSecurity and bug fixes are generally provided only for the last minor version.\nFixes are released either as part of the next minor version or as an on-demand patch version.\n\nSecurity fixes are given priority and might be enough to cause a new version to be released.\n\n## Reporting a Vulnerability\n\nWe encourage responsible disclosure of security vulnerabilities.\nIf you find something suspicious, we encourage and appreciate your report!\n\n### Ways to report\n\nIn order for the vulnerability reports to reach maintainers as soon as possible, the preferred way is to use the \"Report a vulnerability\" button under the \"Security\" tab of the associated GitHub project.\nThis creates a private communication channel between the reporter and the maintainers.\n\nIf you are absolutely unable to or have strong reasons not to use GitHub's vulnerability reporting workflow, please reach out to the Honeycomb security team at [security@honeycomb.io](mailto:security@honeycomb.io).\n\n[gh-organization]: https://github.com/honeycombio\n[bugbounty]: https://www.honeycomb.io/bugbountyprogram\n"
  },
  {
    "path": "SUPPORT.md",
    "content": "# How to Get Help\n\nThis project uses GitHub issues to track bugs, feature requests, and questions about using the project. Please search for existing issues before filing a new one.\n"
  },
  {
    "path": "cmd_build.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\n\tlibhoney \"github.com/honeycombio/libhoney-go\"\n)\n\nfunc commandBuild(cfg *libhoney.Config, filename *string, ciProvider *string) *cobra.Command {\n\t// BUILD - eg: buildevents build $TRAVIS_BUILD_ID $BUILD_START success\n\tbuildCmd := &cobra.Command{\n\t\tUse:   \"build [flags] BUILD_ID BUILD_START OUTCOME\",\n\t\tShort: \"Sends the root span for the entire build\",\n\t\tLong: `\nThe build mode sends the root span for the entire build. It should be called\nwhen the build finishes and records the duration of the entire build. It emits\na URL pointing to the generated trace in Honeycomb to STDOUT.`,\n\t\tArgs:                  argOptions(2, \"success\", \"failure\"),\n\t\tDisableFlagsInUseLine: true,\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\ttraceID := strings.TrimSpace(args[0])\n\t\t\tstartTime := parseUnix(strings.TrimSpace(args[1]))\n\t\t\toutcome := strings.TrimSpace(args[2])\n\n\t\t\tev := createEvent(cfg, *ciProvider, traceID)\n\t\t\tdefer ev.Send()\n\n\t\t\tproviderInfo(*ciProvider, ev)\n\n\t\t\tev.Add(map[string]interface{}{\n\t\t\t\t\"service_name\":  ifClassic(cfg, \"build\", cfg.Dataset),\n\t\t\t\t\"service.name\":  ifClassic(cfg, \"build\", cfg.Dataset),\n\t\t\t\t\"command_name\":  \"build\",\n\t\t\t\t\"trace.span_id\": traceID,\n\t\t\t\t\"name\":          \"build \" + traceID,\n\t\t\t\t\"status\":        outcome,\n\t\t\t\t\"duration_ms\":   time.Since(startTime) / time.Millisecond,\n\t\t\t\t\"source\":        \"buildevents\",\n\t\t\t})\n\t\t\tev.Timestamp = startTime\n\n\t\t\tarbitraryFields(*filename, ev)\n\n\t\t\turl, err := buildURL(cfg, traceID, startTime.Unix())\n\t\t\tif err != nil {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"Unable to create trace URL: %v\\n\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(url)\n\t\t\t}\n\n\t\t\treturn nil\n\t\t},\n\t}\n\treturn buildCmd\n}\n\nfunc argOptions(pos int, opts ...string) cobra.PositionalArgs {\n\treturn cobra.MatchAll(\n\t\tcobra.MinimumNArgs(pos+1),\n\t\tfunc(cmd *cobra.Command, args []string) error {\n\t\t\tfor _, opt := range opts {\n\t\t\t\tif strings.TrimSpace(args[pos]) == opt {\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(opts) == 1 {\n\t\t\t\treturn fmt.Errorf(\"argument at index %d (%q) must be %q\", pos, strings.TrimSpace(args[pos]), opts[0])\n\t\t\t}\n\t\t\treturn fmt.Errorf(\"argument at index %d (%q) must be one of %v\", pos, strings.TrimSpace(args[pos]), opts)\n\t\t},\n\t)\n}\n"
  },
  {
    "path": "cmd_cmd.go",
    "content": "package main\n\nimport (\n\t\"crypto/rand\"\n\t\"fmt\"\n\t\"os\"\n\t\"os/exec\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\n\tpropagation \"github.com/honeycombio/beeline-go/propagation\"\n\tlibhoney \"github.com/honeycombio/libhoney-go\"\n)\n\nfunc commandCmd(cfg *libhoney.Config, filename *string, ciProvider *string) *cobra.Command {\n\t// CMD eg: buildevents cmd $TRAVIS_BUILD_ID $STAGE_SPAN_ID go-test -- go test github.com/honeycombio/hound/...\n\texecCmd := &cobra.Command{\n\t\tUse:   \"cmd [flags] BUILD_ID STEP_ID NAME -- [shell command to execute]\",\n\t\tShort: \"Invoke an individual command that is part of the build.\",\n\t\tLong: `\nThe cmd mode invokes an individual command that is part of the build, such as\nrunning DB migrations or running a specific test suite. It must be able to be\nexpressed as a single shell command - either a process like \"go test\" or a\nshell script. The command to run is the final argument to buildevents and\nwill be launched via \"bash -c\" using \"exec\". The shell can be changed with the\n-s/--shell flag.`,\n\t\tArgs: cobra.MatchAll(\n\t\t\tcobra.MinimumNArgs(4),\n\t\t\tfunc(cmd *cobra.Command, args []string) error {\n\t\t\t\tif cmd.ArgsLenAtDash() != 3 {\n\t\t\t\t\treturn fmt.Errorf(\"use `--` to signify shell command\")\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t),\n\t\tDisableFlagsInUseLine: true,\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\t// Don't show usage if RunE returns an error. This set in RunE\n\t\t\t// instead of when we instantiate the cmd so we don't suppress usage\n\t\t\t// for errors from Args.\n\t\t\tcmd.SilenceUsage = true\n\n\t\t\ttraceID := strings.TrimSpace(args[0])\n\t\t\tstepID := strings.TrimSpace(args[1])\n\t\t\tname := strings.TrimSpace(args[2])\n\t\t\tquiet, _ := cmd.Flags().GetBool(\"quiet\")\n\t\t\tshell, _ := cmd.Flags().GetString(\"shell\")\n\n\t\t\tvar quoted []string\n\t\t\tfor _, s := range args[3:] {\n\t\t\t\tquoted = append(quoted, fmt.Sprintf(\"\\\"%s\\\"\", strings.Replace(s, \"\\\"\", \"\\\\\\\"\", -1)))\n\t\t\t}\n\t\t\tsubcmd := strings.Join(quoted, \" \")\n\n\t\t\tev := createEvent(cfg, *ciProvider, traceID)\n\t\t\tdefer ev.Send()\n\n\t\t\tproviderInfo(*ciProvider, ev)\n\n\t\t\tspanBytes := make([]byte, 16)\n\t\t\trand.Read(spanBytes)\n\n\t\t\tstart := time.Now()\n\n\t\t\t// copy out the current set of fields to avoid later modification\n\t\t\tlocalFields := map[string]interface{}{}\n\t\t\tfor k, v := range ev.Fields() {\n\t\t\t\tlocalFields[k] = v\n\t\t\t}\n\t\t\tvar spanID = fmt.Sprintf(\"%x\", spanBytes)\n\t\t\tprop := &propagation.PropagationContext{\n\t\t\t\tTraceID:      traceID,\n\t\t\t\tParentID:     spanID,\n\t\t\t\tTraceContext: localFields,\n\t\t\t}\n\t\t\terr := runCommand(subcmd, prop, quiet, shell)\n\t\t\tdur := time.Since(start)\n\n\t\t\tev.Add(map[string]interface{}{\n\t\t\t\t\"trace.parent_id\": stepID,\n\t\t\t\t\"trace.span_id\":   spanID,\n\t\t\t\t\"service_name\":    ifClassic(cfg, \"cmd\", cfg.Dataset),\n\t\t\t\t\"service.name\":    ifClassic(cfg, \"cmd\", cfg.Dataset),\n\t\t\t\t\"command_name\":    \"cmd\",\n\t\t\t\t\"name\":            name,\n\t\t\t\t\"duration_ms\":     dur / time.Millisecond,\n\t\t\t\t\"cmd\":             subcmd,\n\t\t\t\t\"source\":          \"buildevents\",\n\t\t\t})\n\t\t\tev.Timestamp = start\n\n\t\t\t// Annotate with arbitrary fields after the command runs\n\t\t\t// this way we can consume a file if the command itself generated one\n\t\t\tarbitraryFields(*filename, ev)\n\n\t\t\tif err == nil {\n\t\t\t\tev.AddField(\"status\", \"success\")\n\t\t\t} else {\n\t\t\t\tev.Add(map[string]interface{}{\n\t\t\t\t\t\"error\":          true,\n\t\t\t\t\t\"status\":         \"failure\",\n\t\t\t\t\t\"failure_reason\": err.Error(),\n\t\t\t\t})\n\t\t\t}\n\n\t\t\treturn err\n\t\t},\n\t}\n\tvar quiet bool\n\tvar shell string\n\texecCmd.Flags().BoolVarP(&quiet, \"quiet\", \"q\", false, \"silence non-cmd output\")\n\texecCmd.Flags().StringVarP(&shell, \"shell\", \"s\", \"/bin/bash\", \"path of shell executable to use for command, must accept -c as an argument\")\n\treturn execCmd\n}\n\nfunc runCommand(subcmd string, prop *propagation.PropagationContext, quiet bool, shell string) error {\n\tif !quiet {\n\t\tfmt.Println(\"running\", shell, \"-c\", subcmd)\n\t}\n\tcmd := exec.Command(shell, \"-c\", subcmd)\n\n\tcmd.Env = append(os.Environ(),\n\t\t\"HONEYCOMB_TRACE=\"+propagation.MarshalHoneycombTraceContext(prop),\n\t)\n\n\tcmd.Stdout = os.Stdout\n\tcmd.Stderr = os.Stderr\n\tcmd.Stdin = os.Stdin\n\n\treturn cmd.Run()\n}\n"
  },
  {
    "path": "cmd_root.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\t\"strings\"\n\n\t\"github.com/spf13/cobra\"\n\n\tlibhoney \"github.com/honeycombio/libhoney-go\"\n)\n\nfunc commandRoot(cfg *libhoney.Config, filename *string, ciProvider *string, serviceName *string) *cobra.Command {\n\troot := &cobra.Command{\n\t\tVersion: Version,\n\t\tUse:     \"buildevents\",\n\t\tShort:   \"buildevents creates events for your CI builds\",\n\t\tLong: `\nThe buildevents executable creates Honeycomb events and tracing information\nabout your Continuous Integration builds.`,\n\t\tPersistentPreRun: func(cmd *cobra.Command, args []string) {\n\t\t\tquiet, _ := cmd.Flags().GetBool(\"quiet\")\n\t\t\tif cfg.IsClassic() {\n\t\t\t\t// if we're in classic mode, we want to behave the same as we always have\n\t\t\t\tif cfg.Dataset == \"\" {\n\t\t\t\t\tcfg.Dataset = \"buildevents\"\n\t\t\t\t}\n\t\t\t\tif *serviceName != \"\" && !quiet {\n\t\t\t\t\tfmt.Fprintf(os.Stderr, \"WARN: classic mode ignores the service name parameter.\\n\")\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// This is the non-classic behavior\n\t\t\t\tif *serviceName != \"\" {\n\t\t\t\t\t// service name was specified, so use it as the dataset\n\t\t\t\t\tif cfg.Dataset != \"\" && !quiet {\n\t\t\t\t\t\t// warn if we're going to ignore a specified dataset\n\t\t\t\t\t\tfmt.Fprintf(os.Stderr, \"WARN: service name was specified, dataset is ignored.\\n\")\n\t\t\t\t\t}\n\t\t\t\t\ttrimmed := strings.TrimSpace(*serviceName)\n\t\t\t\t\tif trimmed != *serviceName && !quiet {\n\t\t\t\t\t\tfmt.Fprintf(os.Stderr, \"WARN: service name contained leading or trailing whitespace, sending to '%s'.\\n\", trimmed)\n\t\t\t\t\t}\n\t\t\t\t\tcfg.Dataset = trimmed\n\t\t\t\t} else {\n\t\t\t\t\t// service_name was not specified\n\t\t\t\t\tif cfg.Dataset == \"\" {\n\t\t\t\t\t\t// neither was specified, so just use the default\n\t\t\t\t\t\tcfg.Dataset = \"buildevents\"\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t}\n\n\troot.PersistentFlags().StringVarP(&cfg.APIKey, \"apikey\", \"k\", \"\", \"[env.BUILDEVENT_APIKEY] the Honeycomb authentication token\")\n\tif apikey, ok := os.LookupEnv(\"BUILDEVENT_APIKEY\"); ok {\n\t\t// https://github.com/spf13/viper/issues/461#issuecomment-366831834\n\t\troot.PersistentFlags().Lookup(\"apikey\").Value.Set(apikey)\n\t}\n\n\troot.PersistentFlags().StringVarP(&cfg.Dataset, \"dataset\", \"d\", \"\", \"[env.BUILDEVENT_DATASET] the name of the Honeycomb dataset to which to send these events\")\n\tif dataset, ok := os.LookupEnv(\"BUILDEVENT_DATASET\"); ok {\n\t\troot.PersistentFlags().Lookup(\"dataset\").Value.Set(dataset)\n\t}\n\n\troot.PersistentFlags().StringVarP(serviceName, \"service_name\", \"n\", \"\", \"[env.BUILDEVENT_SERVICE_NAME] the name of the service to which to send these events; overrides dataset\")\n\tif service_name, ok := os.LookupEnv(\"BUILDEVENT_SERVICE_NAME\"); ok {\n\t\troot.PersistentFlags().Lookup(\"service_name\").Value.Set(service_name)\n\t}\n\n\troot.PersistentFlags().StringVarP(&cfg.APIHost, \"apihost\", \"a\", \"https://api.honeycomb.io\", \"[env.BUILDEVENT_APIHOST] the hostname for the Honeycomb API server to which to send this event\")\n\tif apihost, ok := os.LookupEnv(\"BUILDEVENT_APIHOST\"); ok {\n\t\troot.PersistentFlags().Lookup(\"apihost\").Value.Set(apihost)\n\t}\n\n\troot.PersistentFlags().StringVarP(filename, \"filename\", \"f\", \"\", \"[env.BUILDEVENT_FILE] the path of a text file holding arbitrary key=val pairs (multi-line-capable, logfmt style) to be added to the Honeycomb event\")\n\tif fname, ok := os.LookupEnv(\"BUILDEVENT_FILE\"); ok {\n\t\troot.PersistentFlags().Lookup(\"filename\").Value.Set(fname)\n\t}\n\n\troot.PersistentFlags().StringVarP(ciProvider, \"provider\", \"p\", \"\", \"[env.BUILDEVENT_CIPROVIDER] if unset, will inspect the environment to try to detect common CI providers.\")\n\tprov := os.Getenv(\"BUILDEVENT_CIPROVIDER\")\n\tif prov == \"\" {\n\t\tif _, present := os.LookupEnv(\"TRAVIS\"); present {\n\t\t\tprov = providerTravis\n\t\t} else if _, present := os.LookupEnv(\"CIRCLECI\"); present {\n\t\t\tprov = providerCircle\n\t\t} else if _, present := os.LookupEnv(\"GITLAB_CI\"); present {\n\t\t\tprov = providerGitLab\n\t\t} else if _, present := os.LookupEnv(\"BUILDKITE\"); present {\n\t\t\tprov = providerBuildkite\n\t\t} else if _, present := os.LookupEnv(\"JENKINS-X\"); present {\n\t\t\tprov = providerJenkinsX\n\t\t} else if _, present := os.LookupEnv(\"GOOGLE-CLOUD-BUILD\"); present {\n\t\t\tprov = providerGoogleCloudBuild\n\t\t} else if _, present := os.LookupEnv(\"TF_BUILD\"); present {\n\t\t\tprov = providerAzurePipelines\n\t\t} else if _, present := os.LookupEnv(\"GITHUB_ACTIONS\"); present {\n\t\t\tprov = providerGitHubActions\n\t\t} else if _, present := os.LookupEnv(\"BITBUCKET_BUILD_NUMBER\"); present {\n\t\t\tprov = providerBitbucketPipelines\n\t\t}\n\t}\n\tif prov != \"\" {\n\t\troot.PersistentFlags().Lookup(\"provider\").Value.Set(prov)\n\t}\n\n\treturn root\n}\n"
  },
  {
    "path": "cmd_step.go",
    "content": "package main\n\nimport (\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/spf13/cobra\"\n\n\tlibhoney \"github.com/honeycombio/libhoney-go\"\n)\n\nfunc commandStep(cfg *libhoney.Config, filename *string, ciProvider *string) *cobra.Command {\n\t// STEP - eg: buildevents step $TRAVIS_BUILD_ID $STAGE_SPAN_ID $STAGE_START script\n\tstepCmd := &cobra.Command{\n\t\tUse:   \"step [flags] BUILD_ID STEP_ID START_TIME NAME\",\n\t\tShort: \"Joins a collection of individual commands\",\n\t\tLong: `\nThe step mode represents a block of related commands. In Travis-CI, this is\none of \"install\", \"before_script\", \"script\", and so on. In CircleCI, this\nmost closely maps to a single job. It should be run at the end of the step.`,\n\t\tArgs:                  cobra.ExactArgs(4),\n\t\tDisableFlagsInUseLine: true,\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\ttraceID := strings.TrimSpace(args[0])\n\t\t\tstepID := strings.TrimSpace(args[1])\n\t\t\tstartTime := parseUnix(strings.TrimSpace(args[2]))\n\t\t\tname := strings.TrimSpace(args[3])\n\n\t\t\tev := createEvent(cfg, *ciProvider, traceID)\n\t\t\tdefer ev.Send()\n\n\t\t\tproviderInfo(*ciProvider, ev)\n\n\t\t\tev.Add(map[string]interface{}{\n\t\t\t\t\"trace.parent_id\": traceID,\n\t\t\t\t\"trace.span_id\":   stepID,\n\t\t\t\t\"service_name\":    ifClassic(cfg, \"step\", cfg.Dataset),\n\t\t\t\t\"service.name\":    ifClassic(cfg, \"step\", cfg.Dataset),\n\t\t\t\t\"command_name\":    \"step\",\n\t\t\t\t\"name\":            name,\n\t\t\t\t\"duration_ms\":     time.Since(startTime) / time.Millisecond,\n\t\t\t\t\"source\":          \"buildevents\",\n\t\t\t})\n\t\t\tev.Timestamp = startTime\n\n\t\t\tarbitraryFields(*filename, ev)\n\n\t\t\treturn nil\n\t\t},\n\t}\n\treturn stepCmd\n}\n"
  },
  {
    "path": "cmd_watch.go",
    "content": "package main\n\nimport (\n\t\"context\"\n\t\"fmt\"\n\t\"os\"\n\t\"sort\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\tcircleci \"github.com/jszwedko/go-circleci\"\n\t\"github.com/spf13/cobra\"\n\n\tlibhoney \"github.com/honeycombio/libhoney-go\"\n)\n\n// numChecks is the number of times to verify that we're finished before\n// declaring success in case we enter a transient state with blocked jobs that\n// really will start soon. This can be long - wait for up to 2 minutes (5sec *\n// 24 = 120sec). It's ok for this to be long because it only covers the time\n// when there are existing jobs that are not going to run. Most builds finish\n// with all jobs finishing, so this timer will not caused delayed builds in\n// those cases.\nconst numChecks = 24\n\ntype watchConfig struct {\n\ttimeoutMin int\n\tcircleKey  string\n\tworkflowID string\n\tjobName    string\n}\n\nfunc commandWatch(cfg *libhoney.Config, filename *string, ciProvider *string, wcfg *watchConfig) *cobra.Command {\n\t// WATCH eg: buildevents watch $TRAVIS_BUILD_ID\n\twatchCmd := &cobra.Command{\n\t\tUse:   \"watch BUILD_ID\",\n\t\tShort: \"Polls the CircleCI API and waits until all jobs have finished.\",\n\t\tLong: `\nPolls the CircleCI API and waits until all jobs have finished (either\nsucceeded, failed, or are blocked). It then reports the final status of the\nbuild with the appropriate timers.`,\n\t\tArgs: cobra.MatchAll(\n\t\t\tcobra.ExactArgs(1),\n\t\t\tfunc(cmd *cobra.Command, args []string) error {\n\t\t\t\tif *ciProvider != providerCircle {\n\t\t\t\t\treturn fmt.Errorf(\"watch command only valid for %s\", providerCircle)\n\t\t\t\t}\n\t\t\t\treturn nil\n\t\t\t},\n\t\t),\n\t\tRunE: func(cmd *cobra.Command, args []string) error {\n\t\t\ttraceID := strings.TrimSpace(args[0])\n\n\t\t\tev := createEvent(cfg, *ciProvider, traceID)\n\t\t\tdefer ev.Send()\n\n\t\t\tproviderInfo(*ciProvider, ev)\n\n\t\t\tok, startTime, endTime, jobsFailed, err := waitCircle(context.Background(), *wcfg)\n\t\t\tif err != nil {\n\t\t\t\tfmt.Printf(\"buildevents - Error detected: %s\\n\", err.Error())\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tstatus := \"failed\"\n\t\t\tif ok {\n\t\t\t\tstatus = \"success\"\n\t\t\t}\n\n\t\t\tev.Add(map[string]interface{}{\n\t\t\t\t\"service_name\":  ifClassic(cfg, \"watch\", cfg.Dataset),\n\t\t\t\t\"service.name\":  ifClassic(cfg, \"watch\", cfg.Dataset),\n\t\t\t\t\"command_name\":  \"watch\",\n\t\t\t\t\"trace.span_id\": traceID,\n\t\t\t\t\"name\":          ifClassic(cfg, \"watch \"+traceID, \"watch\"),\n\t\t\t\t\"status\":        status,\n\t\t\t\t\"duration_ms\":   endTime.Sub(startTime) / time.Millisecond,\n\t\t\t\t\"source\":        \"buildevents\",\n\t\t\t\t\"jobs_failed\":   strings.Join(jobsFailed, \",\"),\n\t\t\t})\n\t\t\tev.Timestamp = startTime\n\n\t\t\tarbitraryFields(*filename, ev) // TODO: consider - move this until after the watch timeout??\n\n\t\t\turl, err := buildURL(cfg, traceID, startTime.Unix())\n\t\t\tif err != nil {\n\t\t\t\tfmt.Fprintf(os.Stderr, \"Unable to create trace URL: %v\\n\", err)\n\t\t\t} else {\n\t\t\t\tfmt.Println(url)\n\t\t\t}\n\t\t\treturn nil\n\t\t},\n\t}\n\n\twatchCmd.Flags().IntVarP(&wcfg.timeoutMin, \"timeout\", \"t\", 10, \"[env.BUILDEVENT_TIMEOUT] maximum time (in minutes) that watch should wait before timing out\")\n\tif ts, ok := os.LookupEnv(\"BUILDEVENT_TIMEOUT\"); ok {\n\t\t// This will end up ignoring non-integer values in the envvar\n\t\tif _, err := strconv.Atoi(ts); err == nil {\n\t\t\twatchCmd.Flags().Lookup(\"timeout\").Value.Set(ts)\n\t\t}\n\t}\n\n\twatchCmd.Flags().StringVarP(&wcfg.circleKey, \"circlekey\", \"c\", \"\", \"[env.BUILDEVENT_CIRCLE_API_TOKEN] CircleCI API token used for watching builds for private repositories\")\n\tif tok, ok := os.LookupEnv(\"BUILDEVENT_CIRCLE_API_TOKEN\"); ok {\n\t\twatchCmd.Flags().Lookup(\"circlekey\").Value.Set(tok)\n\t}\n\n\twatchCmd.Flags().StringVarP(&wcfg.workflowID, \"workflowid\", \"w\", \"\", \"[env.CIRCLE_WORKFLOW_ID] CircleCI identifier for the current workflow\")\n\tif wfid, ok := os.LookupEnv(\"CIRCLE_WORKFLOW_ID\"); ok {\n\t\twatchCmd.Flags().Lookup(\"workflowid\").Value.Set(wfid)\n\t}\n\n\twatchCmd.Flags().StringVarP(&wcfg.jobName, \"jobname\", \"j\", \"\", \"[env.CIRCLE_JOB] CircleCI identifier for the current job\")\n\tif jnm, ok := os.LookupEnv(\"CIRCLE_JOB\"); ok {\n\t\twatchCmd.Flags().Lookup(\"jobname\").Value.Set(jnm)\n\t}\n\n\treturn watchCmd\n}\n\n// waitCircle polls the CircleCI API checking for the status of this workflow\n// and the jobs it contains. It returns whether the workflow build succeeded,\n// the time it started, and the time it ended (which will be either nowish or\n// sometime in the past if we timed out). The err returned is for errors polling\n// the CircleCI API, not errors in the build itself.\nfunc waitCircle(parent context.Context, cfg watchConfig) (passed bool, started, ended time.Time, jobsFailed []string, err error) {\n\t// we need a token to query anything; give a helpful error if we have no token\n\tif cfg.circleKey == \"\" {\n\t\treturn false, time.Now(), time.Now().Add(time.Second), nil, fmt.Errorf(\"circle token required to poll the API\")\n\t}\n\tclient := &circleci.Client{Token: cfg.circleKey}\n\twf, err := client.GetWorkflowV2(cfg.workflowID)\n\tif err != nil {\n\t\treturn false, time.Now(), time.Now().Add(time.Second), nil, err\n\t}\n\tstarted = wf.CreatedAt\n\tended = time.Now() // set a default in case we early exit\n\n\t// set up cancellation timeout based on the configured timout duration\n\tdone := make(chan struct{})\n\tctx, cxl := context.WithTimeout(parent, time.Duration(cfg.timeoutMin)*time.Minute)\n\tdefer cxl()\n\n\t// sometimes there's a gap between when a job finishes and the next one starts.\n\t// In that case there are no jobs running and some jobs blocked that could\n\t// still run. If we think the build has passed and finished, let's give it a\n\t// buffer to spin up new jobs before really considering it done. This buffer\n\t// will check for up to 2 minutes\n\tchecksLeft := numChecks + 1 // +1 because we decrement at the beginning of the loop\n\n\tgo func() {\n\t\tdefer close(done)\n\t\ttk := time.NewTicker(5 * time.Second).C\n\t\tfor range tk {\n\t\t\t// check for timeout or pause before the next iteration\n\t\t\tselect {\n\t\t\tcase <-ctx.Done():\n\t\t\t\t// TODO add the fact that it timed out to the trace to say why it failed\n\t\t\t\tfmt.Fprintf(os.Stderr, \"Timeout reached waiting for the workflow to finish\\n\")\n\t\t\t\tended = time.Now()\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t}\n\n\t\t\tresp, err := evalWorkflow(client, cfg.workflowID, cfg.jobName)\n\n\t\t\tif !resp.anyRunning {\n\t\t\t\t// if this is the first time we think we're finished store the timestamp\n\t\t\t\tif checksLeft >= numChecks {\n\t\t\t\t\tended = time.Now()\n\t\t\t\t}\n\n\t\t\t\tif !resp.anyBlocked && err == nil {\n\t\t\t\t\t// we are legit done.\n\t\t\t\t\tpassed = !resp.anyFailed\n\t\t\t\t\tif passed {\n\t\t\t\t\t\tfmt.Println(\"Build passed!\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfmt.Println(\"Build failed!\")\n\t\t\t\t\t\tjobsFailed = resp.failedJobs\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\t// ok, carry on\n\t\t\t\tchecksLeft--\n\t\t\t\tif checksLeft <= 0 {\n\t\t\t\t\t// we're done checking.\n\t\t\t\t\tpassed = !resp.anyFailed\n\t\t\t\t\tif passed {\n\t\t\t\t\t\tfmt.Println(\"Build passed!\")\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfmt.Println(\"Build failed!\")\n\t\t\t\t\t\tjobsFailed = resp.failedJobs\n\t\t\t\t\t}\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tif err != nil {\n\t\t\t\t\t// we previously successfully queried for the workflow; this is likely a\n\t\t\t\t\t// transient error\n\t\t\t\t\tfmt.Printf(\"Querying the CirlceCI API failed with %s; trying %d more times before giving up.\\n\", err.Error(), checksLeft)\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tif resp.anyFailed {\n\t\t\t\t\t// don't bother rechecking if a job has failed\n\t\t\t\t\tfmt.Printf(\"Build failed!\\n\")\n\t\t\t\t\tjobsFailed = resp.failedJobs\n\t\t\t\t\tended = time.Now()\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\t// yay looks like maybe we're done?\n\t\t\t\tfmt.Printf(\"Build appears finished; checking %d more times to make sure.\\n\", checksLeft)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// if we previously thought we were finished but now realize we weren't,\n\t\t\t// reset the check counter so we try 3 times again next time we think we're\n\t\t\t// finished.\n\t\t\tpassed = false\n\t\t\tchecksLeft = numChecks\n\t\t}\n\t}()\n\n\t<-done\n\treturn passed, started, ended, jobsFailed, nil\n}\n\ntype evalWorkflowResponse struct {\n\tanyRunning bool\n\tanyFailed  bool\n\tanyBlocked bool\n\tfailedJobs []string\n}\n\n// evalWorkflow looks at the CircleCI API for the list of jobs in this workflow\n// and decides whether the build has finished and if finished, whether it\n// failed. If an error is returned, it represents an error talking to the\n// CircleCI API, not an error with the workflow.\nfunc evalWorkflow(client *circleci.Client, wfID string, jobName string) (evalWorkflowResponse, error) {\n\tfmt.Printf(\"%s: polling for jobs: \", time.Now().Format(time.StampMilli))\n\twfJobs, err := getJobs(client, wfID)\n\tif err != nil {\n\t\tfmt.Printf(\"error polling: %s\\n\", err.Error())\n\t\treturn evalWorkflowResponse{\n\t\t\tanyRunning: true,\n\t\t\tanyFailed:  true,\n\t\t}, err\n\t}\n\tfmt.Println(summarizeJobList(wfJobs))\n\n\t// defaults all to false\n\tresp := evalWorkflowResponse{}\n\tfor _, job := range wfJobs {\n\t\t// skip ourself so we don't wait if we're the only job running\n\t\tif job.Name == jobName {\n\t\t\tcontinue\n\t\t}\n\n\t\tswitch job.Status {\n\t\tcase \"success\":\n\t\t\t// success means it finished and passed, don't keep track of it\n\t\t\tcontinue\n\t\tcase \"blocked\":\n\t\t\t// blocked means it can't yet run, but that could be because either\n\t\t\t// it's waiting on a running job, depends on a failed job, or\n\t\t\t// it's not configured to run this build (because of a tag or something)\n\t\t\tresp.anyBlocked = true\n\t\t\tcontinue\n\t\tcase \"not_running\":\n\t\t\t// not_running is the same as queued\n\t\t\tfallthrough\n\t\tcase \"queued\":\n\t\t\t// queued means a job is due to start running soon, so we consider it running\n\t\t\t// already.\n\t\t\tresp.anyRunning = true\n\t\tcase \"failed\":\n\t\t\tresp.anyFailed = true\n\t\t\tresp.failedJobs = append(resp.failedJobs, job.Name)\n\t\t\tcontinue\n\t\tcase \"running\":\n\t\t\tresp.anyRunning = true\n\t\t}\n\t}\n\n\treturn resp, nil\n}\n\n// getJobs queries the CircleCI API for a list of all jobs in the current workflow\nfunc getJobs(client *circleci.Client, wfID string) ([]*circleci.WorkflowJob, error) {\n\t// get the list of jobs, paging if necessary\n\twfJobs, more, err := client.ListWorkflowV2Jobs(wfID, nil)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tfor more != nil {\n\t\t// TODO only print this in debug mode\n\t\tfmt.Printf(\"getting more jobs! next page is %s\\n\", *more)\n\t\tvar moreJobs []*circleci.WorkflowJob\n\t\tmoreJobs, more, err = client.ListWorkflowV2Jobs(wfID, nil)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\twfJobs = append(wfJobs, moreJobs...)\n\t}\n\treturn wfJobs, nil\n}\n\n// summarizeJobList takes a list of jobs and returns a string summary\nfunc summarizeJobList(wfJobs []*circleci.WorkflowJob) string {\n\tif len(wfJobs) == 0 {\n\t\treturn \"no jobs found\"\n\t}\n\n\t// look at all the jobs and count how many are in each status state\n\tcountByStatus := map[string]int{}\n\tfor _, job := range wfJobs {\n\t\tcountByStatus[job.Status]++\n\t}\n\n\t// sort the statuses present to print them in a consistent order\n\tsortedStatusList := make([]string, 0, len(countByStatus))\n\tfor key := range countByStatus {\n\t\tsortedStatusList = append(sortedStatusList, key)\n\t}\n\tsort.Strings(sortedStatusList)\n\n\t// create a list of printable status counts\n\tstatusStrings := make([]string, 0, len(countByStatus))\n\tfor i := 0; i < len(countByStatus); i++ {\n\t\tstatus := sortedStatusList[i]\n\t\tcount := countByStatus[status]\n\t\tstatusStrings = append(statusStrings, fmt.Sprintf(\"%d %s\", count, status))\n\t}\n\n\t// join the list of printable statuses to make one nice line\n\treturn strings.Join(statusStrings, \", \")\n}\n"
  },
  {
    "path": "common.go",
    "content": "package main\n\nimport (\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"net/url\"\n\t\"os\"\n\t\"path\"\n\t\"regexp\"\n\t\"runtime\"\n\t\"strconv\"\n\t\"strings\"\n\t\"time\"\n\n\t\"github.com/kr/logfmt\"\n\n\tlibhoney \"github.com/honeycombio/libhoney-go\"\n\t\"github.com/honeycombio/libhoney-go/transmission\"\n)\n\nfunc createEvent(cfg *libhoney.Config, provider string, traceID string) *libhoney.Event {\n\tlibhoney.UserAgentAddition = fmt.Sprintf(\"buildevents/%s\", Version)\n\tif provider != \"\" {\n\t\tlibhoney.UserAgentAddition += fmt.Sprintf(\" (%s)\", provider)\n\t}\n\n\tif cfg.APIKey == \"\" {\n\t\tcfg.Transmission = &transmission.WriterSender{}\n\t}\n\tlibhoney.Init(*cfg)\n\n\tev := libhoney.NewEvent()\n\tif provider != \"\" {\n\t\tev.AddField(\"ci_provider\", provider)\n\t}\n\tev.AddField(\"trace.trace_id\", traceID)\n\tev.AddField(\"meta.version\", Version)\n\n\tev.AddField(\"meta.os\", runtime.GOOS)\n\tev.AddField(\"meta.arch\", runtime.GOARCH)\n\n\treturn ev\n}\n\n// providerInfo adds a bunch of fields to every span with useful information\n// about the build, gleaned from known providers\nfunc providerInfo(provider string, ev *libhoney.Event) {\n\t// envVars is a map of environment variable to event field name\n\tvar envVars map[string]string\n\tswitch strings.ToLower(provider) {\n\tcase \"circleci\", \"circle-ci\", \"circle\":\n\t\tenvVars = map[string]string{\n\t\t\t\"CIRCLE_BRANCH\":         \"branch\",\n\t\t\t\"CIRCLE_BUILD_NUM\":      \"build_num\",\n\t\t\t\"CIRCLE_BUILD_URL\":      \"build_url\", // overwrites buildevent_url+traceID\n\t\t\t\"CIRCLE_JOB\":            \"job_name\",\n\t\t\t\"CIRCLE_PR_NUMBER\":      \"pr_number\",\n\t\t\t\"CIRCLE_PR_REPONAME\":    \"pr_repo\",\n\t\t\t\"CIRCLE_PR_USER\":        \"pr_user\",\n\t\t\t\"CIRCLE_REPOSITORY_URL\": \"repo\",\n\t\t}\n\tcase \"travis-ci\", \"travisci\", \"travis\":\n\t\tenvVars = map[string]string{\n\t\t\t\"TRAVIS_BRANCH\":              \"branch\",\n\t\t\t\"TRAVIS_BUILD_NUMBER\":        \"build_num\",\n\t\t\t\"TRAVIS_BUILD_WEB_URL\":       \"build_url\",\n\t\t\t\"TRAVIS_PULL_REQUEST\":        \"pr_number\",\n\t\t\t\"TRAVIS_PULL_REQUEST_BRANCH\": \"pr_branch\",\n\t\t\t\"TRAVIS_PULL_REQUEST_SLUG\":   \"pr_repo\",\n\t\t\t\"TRAVIS_REPO_SLUG\":           \"repo\",\n\t\t}\n\tcase \"gitlab-ci\", \"gitlabci\", \"gitlab\":\n\t\tenvVars = map[string]string{\n\t\t\t\"CI_COMMIT_REF_NAME\":                   \"branch\",\n\t\t\t\"CI_PIPELINE_ID\":                       \"build_num\",\n\t\t\t\"CI_PIPELINE_URL\":                      \"build_url\",\n\t\t\t\"CI_MERGE_REQUEST_ID\":                  \"pr_number\",\n\t\t\t\"CI_MERGE_REQUEST_SOURCE_BRANCH_NAME\":  \"pr_branch\",\n\t\t\t\"CI_MERGE_REQUEST_SOURCE_PROJECT_PATH\": \"pr_repo\",\n\t\t\t\"CI_PROJECT_URL\":                       \"repo\",\n\t\t}\n\n\tcase \"buildkite\", \"buildkiteci\", \"build-kite\":\n\t\tenvVars = map[string]string{\n\t\t\t\"BUILDKITE_BRANCH\":            \"branch\",\n\t\t\t\"BUILDKITE_BUILD_NUMBER\":      \"build_num\",\n\t\t\t\"BUILDKITE_BUILD_URL\":         \"build_url\",\n\t\t\t\"BUILDKITE_PULL_REQUEST\":      \"pr_number\",\n\t\t\t\"BUILDKITE_PULL_REQUEST_REPO\": \"pr_repo\",\n\t\t\t\"BUILDKITE_REPO\":              \"repo\",\n\t\t}\n\tcase \"jenkinsx\", \"jenkins-x\":\n\t\tenvVars = map[string]string{\n\t\t\t\"BRANCH_NAME\":  \"branch\",\n\t\t\t\"BUILD_NUMBER\": \"build_num\",\n\t\t\t\"PULL_NUMBER\":  \"pr_number\",\n\t\t\t\"REPO_NAME\":    \"repo\",\n\t\t}\n\n\tcase \"google-cloud-build\", \"cloud-build\", \"gcb\":\n\t\tenvVars = map[string]string{\n\t\t\t\"BRANCH_NAME\": \"branch\",\n\t\t\t\"BUILD_ID\":    \"build_num\",\n\t\t\t\"HEAD_BRANCH\": \"pr_branch\",\n\t\t\t\"REPO_OWNER\":  \"pr_user\",\n\t\t\t\"REPO_NAME\":   \"repo\",\n\t\t}\n\n\tcase \"azure-pipelines\", \"azure-devops\", \"vsts\", \"tfs\":\n\t\tenvVars = map[string]string{\n\t\t\t\"BUILD_SOURCEBRANCHNAME\":               \"branch\",\n\t\t\t\"BUILD_BUILDID\":                        \"build_id\",\n\t\t\t\"BUILD_BUILDNUMBER\":                    \"build_number\",\n\t\t\t\"SYSTEM_JOBDISPLAYNAME\":                \"job_name\",\n\t\t\t\"SYSTEM_STAGEDISPLAYNAME\":              \"stage_name\",\n\t\t\t\"SYSTEM_PULLREQUEST_PULLREQUESTID\":     \"pr_id\",\n\t\t\t\"SYSTEM_PULLREQUEST_PULLREQUESTNUMBER\": \"pr_number\",\n\t\t\t\"SYSTEM_PULLREQUEST_SOURCEBRANCH\":      \"pr_branch\",\n\t\t\t\"BUILD_REQUESTEDFOR\":                   \"build_user\",\n\t\t\t\"BUILD_REPOSITORY_URI\":                 \"repo\",\n\t\t}\n\n\tcase \"github-actions\", \"githubactions\", \"github\", \"gha-buildevents\":\n\t\tenvVars = map[string]string{\n\t\t\t\"GITHUB_REF\":        \"branch\",\n\t\t\t\"GITHUB_RUN_ID\":     \"build_num\",\n\t\t\t\"GITHUB_WORKFLOW\":   \"workflow_name\",\n\t\t\t\"GITHUB_HEAD_REF\":   \"pr_branch\",\n\t\t\t\"GITHUB_ACTOR\":      \"pr_user\",\n\t\t\t\"GITHUB_REPOSITORY\": \"repo\",\n\t\t}\n\n\tcase \"bitbucket-pipelines\", \"bitbucketpipelines\", \"bitbucket\":\n\t\tenvVars = map[string]string{\n\t\t\t\"BITBUCKET_BRANCH\":              \"branch\",\n\t\t\t\"BITBUCKET_PIPELINE_UUID\":       \"pipeline_id\",\n\t\t\t\"BITBUCKET_BUILD_NUMBER\":        \"build_num\",\n\t\t\t\"BITBUCKET_REPO_FULL_NAME\":      \"repo\",\n\t\t\t\"BITBUCKET_PR_ID\":               \"pr_id\",\n\t\t\t\"BITBUCKET_STEP_TRIGGERER_UUID\": \"build_user\",\n\t\t}\n\t}\n\tfor envVar, fieldName := range envVars {\n\t\tif val, ok := os.LookupEnv(envVar); ok {\n\t\t\tev.AddField(fieldName, val)\n\t\t}\n\t}\n}\n\n// arbitraryFields adds an arbitrary set of fields provided by the end user\nfunc arbitraryFields(loc string, ev *libhoney.Event) {\n\tif loc == \"\" {\n\t\treturn\n\t}\n\n\tdata, err := ioutil.ReadFile(loc)\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"unable to read %q: %v\\n\", loc, err)\n\t\treturn\n\t}\n\n\terr = logfmt.Unmarshal(\n\t\tdata,\n\t\tlogfmt.HandlerFunc(func(key, val []byte) error {\n\t\t\tif f, err := strconv.ParseFloat(string(val), 64); err == nil {\n\t\t\t\tev.AddField(string(key), f)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tif b, err := strconv.ParseBool(string(val)); err == nil {\n\t\t\t\tev.AddField(string(key), b)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tev.AddField(string(key), string(val))\n\t\t\treturn nil\n\t\t}),\n\t)\n\tif err != nil {\n\t\tfmt.Fprintf(os.Stderr, \"problems loading from %q: %v\\n\", loc, err)\n\t}\n}\n\n// parseUnix reads the input text as a Unix timestamp (to the second)\nfunc parseUnix(ts string) time.Time {\n\tsecondsSinceEpoch, _ := strconv.ParseInt(strings.TrimSpace(ts), 10, 64)\n\tunix := time.Unix(secondsSinceEpoch, 0)\n\tif unix == time.Unix(0, 0) {\n\t\tfmt.Fprintf(os.Stderr, \"couldn't parse startTime of %q\\n\", ts)\n\t\tunix = time.Now()\n\t}\n\treturn unix\n}\n\n// slugify turns a name into a slug. It is idempotent to things that are already slugs.\nfunc slugify(name string) string {\n\tslugReplaceRegex := regexp.MustCompile(`[^a-z0-9_~\\.-]`)\n\treturn slugReplaceRegex.ReplaceAllString(strings.ToLower(name), \"-\")\n}\n\nfunc buildURL(cfg *libhoney.Config, traceID string, ts int64) (string, error) {\n\tteam, environment, err := libhoney.GetTeamAndEnvironment(*cfg)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to verify API key: %w\", err)\n\t}\n\tuiHost := strings.Replace(cfg.APIHost, \"api\", \"ui\", 1)\n\tu, err := url.Parse(uiHost)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"unable to infer UI host: %s\", uiHost)\n\t}\n\n\tpathSegments := []string{team}\n\tif !cfg.IsClassic() {\n\t\tpathSegments = append(pathSegments, \"environments\", environment)\n\t}\n\tpathSegments = append(pathSegments, \"datasets\", slugify(cfg.Dataset), \"trace\")\n\tu.Path = path.Join(pathSegments...)\n\tendTime := time.Now().Add(10 * time.Minute).Unix()\n\n\tv := url.Values{}\n\tv.Set(\"trace_id\", traceID)\n\tv.Set(\"trace_start_ts\", strconv.FormatInt(ts, 10))\n\tv.Set(\"trace_end_ts\", strconv.FormatInt(endTime, 10))\n\tu.RawQuery = v.Encode()\n\n\treturn u.String(), nil\n}\n\nfunc ifClassic(cfg *libhoney.Config, classicVal, elseVal string) string {\n\tif cfg.IsClassic() {\n\t\treturn classicVal\n\t}\n\treturn elseVal\n}\n"
  },
  {
    "path": "common_test.go",
    "content": "package main\n\nimport (\n\t\"net/http\"\n\t\"net/http/httptest\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/honeycombio/libhoney-go\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestBuildUrl(t *testing.T) {\n\ttestCases := []struct {\n\t\tName        string\n\t\tAPIKey      string\n\t\tClassic     bool\n\t\texpectedUrl string\n\t}{\n\t\t{Name: \"classic\", Classic: true, APIKey: \"25f7d47575430a8fafea5b7d70a6af09\", expectedUrl: \"test_team/datasets/test_dataset/trace\"},\n\t\t{Name: \"classic ingest key\", Classic: true, APIKey: \"hcaic_1234567890123456789012345678901234567890123456789012345678\", expectedUrl: \"test_team/datasets/test_dataset/trace\"},\n\t\t{Name: \"non classic v2 configuration key\", Classic: false, APIKey: \"lcYrFflRUR6rHbIifwqhfG\", expectedUrl: \"test_team/environments/test_env/datasets/test_dataset/trace\"},\n\t\t{Name: \"non classic ingest key\", Classic: false, APIKey: \"hcxik_01hqk4k20cjeh63wca8vva5stw70nft6m5n8wr8f5mjx3762s8269j50wc\", expectedUrl: \"test_team/environments/test_env/datasets/test_dataset/trace\"},\n\t}\n\n\tfor _, tc := range testCases {\n\t\tt.Run(tc.Name, func(t *testing.T) {\n\t\t\tserver := httptest.NewServer(\n\t\t\t\thttp.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\t\t\t\tassert.Equal(t, \"/1/auth\", r.URL.Path)\n\t\t\t\t\tassert.Equal(t, []string{tc.APIKey}, r.Header[\"X-Honeycomb-Team\"])\n\n\t\t\t\t\tif tc.Classic {\n\t\t\t\t\t\tw.Write([]byte(`{\"team\":{\"slug\":\"test_team\"}}`))\n\t\t\t\t\t} else {\n\t\t\t\t\t\tw.Write([]byte(`{\"team\":{\"slug\":\"test_team\"},\"environment\":{\"slug\":\"test_env\"}}`))\n\t\t\t\t\t}\n\t\t\t\t}),\n\t\t\t)\n\t\t\tdefer server.Close()\n\n\t\t\tconfig := libhoney.Config{\n\t\t\t\tAPIKey:  tc.APIKey,\n\t\t\t\tAPIHost: server.URL,\n\t\t\t\tDataset: \"test_dataset\",\n\t\t\t}\n\n\t\t\turl, err := buildURL(&config, \"trace_id\", time.Now().UTC().UnixNano())\n\t\t\tassert.Nil(t, err)\n\t\t\texpectedUrl := server.URL + \"/\" + tc.expectedUrl\n\t\t\tassert.Equal(t, expectedUrl, url[:strings.IndexByte(url, '?')])\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/honeycombio/buildevents\n\ngo 1.23.0\n\ntoolchain go1.24.1\n\nrequire (\n\tgithub.com/honeycombio/beeline-go v1.19.0\n\tgithub.com/honeycombio/libhoney-go v1.25.0\n\tgithub.com/jszwedko/go-circleci v0.3.0\n\tgithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515\n\tgithub.com/spf13/cobra v1.9.1\n\tgithub.com/stretchr/testify v1.10.0\n)\n\nrequire (\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a // indirect\n\tgithub.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 // indirect\n\tgithub.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 // indirect\n\tgithub.com/inconshreveable/mousetrap v1.1.0 // indirect\n\tgithub.com/klauspost/compress v1.17.11 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/spf13/pflag v1.0.6 // indirect\n\tgithub.com/vmihailenco/msgpack/v5 v5.4.1 // indirect\n\tgithub.com/vmihailenco/tagparser/v2 v2.0.0 // indirect\n\tgopkg.in/alexcesaro/statsd.v2 v2.0.0 // indirect\n\tgopkg.in/yaml.v3 v3.0.1 // indirect\n)\n\nreplace github.com/jszwedko/go-circleci => github.com/maplebed/go-circleci v0.0.0-20191121000249-089ef54587e5\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/DataDog/zstd v1.5.6 h1:LbEglqepa/ipmmQJUDnSsfvA8e8IStVcGaFWDuxvGOY=\ngithub.com/DataDog/zstd v1.5.6/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw=\ngithub.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a h1:yDWHCSQ40h88yih2JAcL6Ls/kVkSE8GFACTGVnMPruw=\ngithub.com/facebookgo/clock v0.0.0-20150410010913-600d898af40a/go.mod h1:7Ga40egUymuWXxAe151lTNnCv97MddSOVsjpPPkityA=\ngithub.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0=\ngithub.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=\ngithub.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01 h1:IeaD1VDVBPlx3viJT9Md8if8IxxJnO+x0JCGb054heg=\ngithub.com/facebookgo/limitgroup v0.0.0-20150612190941-6abd8d71ec01/go.mod h1:ypD5nozFk9vcGw1ATYefw6jHe/jZP++Z15/+VTMcWhc=\ngithub.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52 h1:a4DFiKFJiDRGFD1qIcqGLX/WlUMD9dyLSLDt+9QZgt8=\ngithub.com/facebookgo/muster v0.0.0-20150708232844-fd3d7953fd52/go.mod h1:yIquW87NGRw1FU5p5lEkpnt/QxoH5uPAOUlOVkAUuMg=\ngithub.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=\ngithub.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg=\ngithub.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk=\ngithub.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=\ngithub.com/honeycombio/beeline-go v1.19.0 h1:FikgbX3PgivINs5kQHby6aVzhXZt6RtKvH6TGDSWV4c=\ngithub.com/honeycombio/beeline-go v1.19.0/go.mod h1:NsFeKTliw5xrG4s1/P3sOCaip+gcBYZktY5SuS4xKao=\ngithub.com/honeycombio/libhoney-go v1.25.0 h1:r33tlX90HtafK0bgRcjfNnsrJ9ZMTKuI/1DYaOFCc1o=\ngithub.com/honeycombio/libhoney-go v1.25.0/go.mod h1:Fc0HjqlwYf5xy6H34EItpOverAGbCixnYOX3YTUQovg=\ngithub.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=\ngithub.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=\ngithub.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc=\ngithub.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY=\ngithub.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=\ngithub.com/maplebed/go-circleci v0.0.0-20191121000249-089ef54587e5 h1:MkahNIXXDmLmqo3rHm8lS6OwiXSNHQdlrSAd/V9ywhc=\ngithub.com/maplebed/go-circleci v0.0.0-20191121000249-089ef54587e5/go.mod h1:OW/yiyLmpZqdbYUHRuFS83n1TpphzLe6sDFvOa8xX4w=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=\ngithub.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=\ngithub.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=\ngithub.com/spf13/pflag v1.0.6 h1:jFzHGLGAlb3ruxLB8MhbI6A8+AQX/2eW4qeyNZXNp2o=\ngithub.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=\ngithub.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=\ngithub.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=\ngithub.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=\ngithub.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=\ngithub.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=\ngithub.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=\ngopkg.in/alexcesaro/statsd.v2 v2.0.0 h1:FXkZSCZIH17vLCO5sO2UucTHsH9pc+17F6pl3JVCwMc=\ngopkg.in/alexcesaro/statsd.v2 v2.0.0/go.mod h1:i0ubccKGzBVNBpdGV5MocxyA/XlLUJzA7SLonnE4drU=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=\ngopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=\n"
  },
  {
    "path": "main.go",
    "content": "package main\n\nimport (\n\t\"errors\"\n\t\"os\"\n\n\t\"os/exec\"\n\n\tlibhoney \"github.com/honeycombio/libhoney-go\"\n)\n\n// Version will be set by CircleCI based on a git tag and the commit hash\nvar Version = \"dev\"\n\nconst (\n\tproviderTravis             = \"Travis-CI\"\n\tproviderCircle             = \"CircleCI\"\n\tproviderGitLab             = \"GitLab-CI\"\n\tproviderBuildkite          = \"Buildkite\"\n\tproviderJenkinsX           = \"Jenkins-X\"\n\tproviderGoogleCloudBuild   = \"Google-Cloud-Build\"\n\tproviderAzurePipelines     = \"Azure-Pipelines\"\n\tproviderGitHubActions      = \"GitHub-Actions\"\n\tproviderBitbucketPipelines = \"Bitbucket-Pipelines\"\n)\n\nfunc main() {\n\tdefer libhoney.Close()\n\tvar config libhoney.Config\n\tvar filename string\n\tvar ciProvider string\n\tvar wcfg watchConfig\n\tvar serviceName string\n\n\troot := commandRoot(&config, &filename, &ciProvider, &serviceName)\n\n\t// Put 'em all together\n\troot.AddCommand(\n\t\tcommandBuild(&config, &filename, &ciProvider),\n\t\tcommandStep(&config, &filename, &ciProvider),\n\t\tcommandCmd(&config, &filename, &ciProvider),\n\t\tcommandWatch(&config, &filename, &ciProvider, &wcfg),\n\t)\n\n\t// Do the work\n\tif err := root.Execute(); err != nil {\n\t\tlibhoney.Close()\n\n\t\t// If the underlying command returned a specific exit code, we need\n\t\t// to exit it with it as well to act transparently.\n\t\tvar cmdErr *exec.ExitError\n\t\tif errors.As(err, &cmdErr) {\n\t\t\tos.Exit(cmdErr.ExitCode())\n\t\t}\n\t\tos.Exit(1)\n\t}\n}\n"
  }
]