├── .editorconfig ├── .github ├── dependabot.yml └── workflows │ ├── ensure-docs-compiled.yaml │ ├── notify-integration-release-via-manual.yaml │ ├── notify-integration-release-via-tag.yaml │ ├── release.yml │ ├── run-tests.yml │ └── test-plugin-example.yml ├── .gitignore ├── .goreleaser.yml ├── .web-docs ├── README.md ├── components │ └── data-source │ │ ├── commit │ │ └── README.md │ │ ├── repository │ │ └── README.md │ │ └── tree │ │ └── README.md ├── metadata.hcl └── scripts │ └── compile-to-webdocs.sh ├── GNUmakefile ├── LICENSE ├── README.md ├── common └── common.go ├── datasource ├── commit │ ├── data.go │ ├── data.hcl2spec.go │ ├── data_acc_test.go │ └── test-fixtures │ │ └── template.pkr.hcl ├── repository │ ├── data.go │ ├── data.hcl2spec.go │ ├── data_acc_test.go │ └── test-fixtures │ │ └── template.pkr.hcl └── tree │ ├── data.go │ ├── data.hcl2spec.go │ ├── data_acc_test.go │ └── test-fixtures │ └── template.pkr.hcl ├── docs ├── README.md └── datasources │ ├── commit.mdx │ ├── repository.mdx │ └── tree.mdx ├── example ├── README.md ├── commit.pkr.hcl ├── repository.pkr.hcl └── tree.pkr.hcl ├── go.mod ├── go.sum └── main.go /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://editorconfig.org/ 2 | root = true 3 | 4 | [*] 5 | trim_trailing_whitespace = true 6 | end_of_line = lf 7 | insert_final_newline = true 8 | charset = utf-8 9 | 10 | [{GNUmakefile,go.mod,go.sum,*.go}] 11 | indent_style = tab 12 | indent_size = 4 13 | 14 | [*.hcl] 15 | indent_style = space 16 | indent_size = 2 17 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "gomod" 9 | directory: "/" 10 | schedule: 11 | interval: "weekly" 12 | - package-ecosystem: "github-actions" 13 | directory: "/" 14 | schedule: 15 | interval: "weekly" 16 | 17 | -------------------------------------------------------------------------------- /.github/workflows/ensure-docs-compiled.yaml: -------------------------------------------------------------------------------- 1 | name: Ensure Docs are Compiled 2 | on: 3 | push: 4 | jobs: 5 | ensure-docs-compiled: 6 | runs-on: ubuntu-latest 7 | steps: 8 | - name: Checkout 🛎 9 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 10 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 11 | - shell: bash 12 | run: make generate 13 | - shell: bash 14 | run: | 15 | if [[ -z "$(git status -s)" ]]; then 16 | echo "OK" 17 | else 18 | echo "Docs have been updated, but the compiled docs have not been committed." 19 | echo "Run 'make generate and commit the result to resolve this error." 20 | exit 1 21 | fi 22 | 23 | -------------------------------------------------------------------------------- /.github/workflows/notify-integration-release-via-manual.yaml: -------------------------------------------------------------------------------- 1 | # Manual release workflow is used for deploying documentation updates 2 | # on the specified branch without making an official plugin release. 3 | name: Notify Integration Release (Manual) 4 | on: 5 | workflow_dispatch: 6 | inputs: 7 | version: 8 | description: "The release version (semver)" 9 | default: 1.0.0 10 | required: false 11 | branch: 12 | description: "A branch or SHA" 13 | default: 'main' 14 | required: false 15 | jobs: 16 | notify-release: 17 | runs-on: ubuntu-latest 18 | steps: 19 | - name: Checkout this repo 20 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 21 | with: 22 | ref: ${{ github.event.inputs.branch }} 23 | # Ensure that Docs are Compiled 24 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 25 | - shell: bash 26 | run: make generate 27 | - shell: bash 28 | run: | 29 | if [[ -z "$(git status -s)" ]]; then 30 | echo "OK" 31 | else 32 | echo "Docs have been updated, but the compiled docs have not been committed." 33 | echo "Run 'make generate', and commit the result to resolve this error." 34 | exit 1 35 | fi 36 | # Perform the Release 37 | - name: Checkout integration-release-action 38 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 39 | with: 40 | repository: hashicorp/integration-release-action 41 | path: ./integration-release-action 42 | - name: Notify Release 43 | uses: ./integration-release-action 44 | with: 45 | # The integration identifier will be used by the Packer team to register the integration 46 | # the expected format is packer// 47 | integration_identifier: "packer/ethanmdavidson/git" 48 | release_version: ${{ github.event.inputs.version }} 49 | release_sha: ${{ github.event.inputs.branch }} 50 | github_token: ${{ secrets.GITHUB_TOKEN }} 51 | -------------------------------------------------------------------------------- /.github/workflows/notify-integration-release-via-tag.yaml: -------------------------------------------------------------------------------- 1 | name: Notify Integration Release (Tag) 2 | on: 3 | push: 4 | tags: 5 | - '*.*.*' # Proper releases 6 | jobs: 7 | strip-version: 8 | runs-on: ubuntu-latest 9 | outputs: 10 | packer-version: ${{ steps.strip.outputs.packer-version }} 11 | steps: 12 | - name: Strip leading v from version tag 13 | id: strip 14 | env: 15 | REF: ${{ github.ref_name }} 16 | run: | 17 | echo "packer-version=$(echo "$REF" | sed -E 's/v?([0-9]+\.[0-9]+\.[0-9]+)/\1/')" >> "$GITHUB_OUTPUT" 18 | notify-release: 19 | needs: 20 | - strip-version 21 | runs-on: ubuntu-latest 22 | steps: 23 | - name: Checkout this repo 24 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 25 | with: 26 | ref: ${{ github.ref }} 27 | # Ensure that Docs are Compiled 28 | - uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 29 | - shell: bash 30 | run: make generate 31 | - shell: bash 32 | run: | 33 | if [[ -z "$(git status -s)" ]]; then 34 | echo "OK" 35 | else 36 | echo "Docs have been updated, but the compiled docs have not been committed." 37 | echo "Run 'make generate', and commit the result to resolve this error." 38 | exit 1 39 | fi 40 | # Perform the Release 41 | - name: Checkout integration-release-action 42 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 43 | with: 44 | repository: hashicorp/integration-release-action 45 | path: ./integration-release-action 46 | - name: Notify Release 47 | uses: ./integration-release-action 48 | with: 49 | # The integration identifier will be used by the Packer team to register the integration 50 | # the expected format is packer// 51 | integration_identifier: "packer/ethanmdavidson/git" 52 | release_version: ${{ needs.strip-version.outputs.packer-version }} 53 | release_sha: ${{ github.ref }} 54 | github_token: ${{ secrets.GITHUB_TOKEN }} 55 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # This GitHub action can publish assets for release when a tag is created. 2 | # Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). 3 | # 4 | # This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your 5 | # private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` 6 | # secret. If you would rather own your own GPG handling, please fork this action 7 | # or use an alternative one for key handling. 8 | # 9 | # You will need to pass the `--batch` flag to `gpg` in your signing step 10 | # in `goreleaser` to indicate this is being used in a non-interactive mode. 11 | # 12 | name: release 13 | on: 14 | push: 15 | tags: 16 | - 'v*' 17 | jobs: 18 | goreleaser: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 23 | 24 | - name: Unshallow 25 | run: git fetch --prune --unshallow 26 | 27 | - name: Set up Go 28 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 29 | with: 30 | go-version-file: 'go.mod' 31 | cache: true 32 | 33 | - name: Describe plugin 34 | id: plugin_describe 35 | run: echo "::set-output name=api_version::$(go run . describe | jq -r '.api_version')" 36 | 37 | - name: Import GPG key 38 | id: import_gpg 39 | uses: crazy-max/ghaction-import-gpg@e89d40939c28e39f97cf32126055eeae86ba74ec # v6.3.0 40 | with: 41 | gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} 42 | passphrase: ${{ secrets.PASSPHRASE }} 43 | 44 | - name: Run GoReleaser 45 | uses: goreleaser/goreleaser-action@9c156ee8a17a598857849441385a2041ef570552 # v6.3.0 46 | with: 47 | version: latest 48 | args: release --clean 49 | env: 50 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 51 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 52 | API_VERSION: ${{ steps.plugin_describe.outputs.api_version }} 53 | -------------------------------------------------------------------------------- /.github/workflows/run-tests.yml: -------------------------------------------------------------------------------- 1 | #Runs all the tests! Triggers on push and PR for quick feedback. 2 | #Tests are not very comprehensive right now, so don't put too much faith in this. 3 | name: run tests 4 | 5 | on: 6 | push: 7 | branches: 8 | - main 9 | pull_request: 10 | branches: 11 | - main 12 | 13 | jobs: 14 | test: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - name: Checkout 18 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 19 | 20 | - name: Set up Go 21 | uses: actions/setup-go@d35c59abb061a4a6fb18e82ac0862c26744d6ab5 # v5.5.0 22 | with: 23 | go-version-file: 'go.mod' 24 | cache: true 25 | 26 | - name: Install Tools 27 | run: make prep 28 | 29 | - name: Execute tests 30 | run: make test && make testacc 31 | 32 | - name: Upload test artifacts for debugging 33 | uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 34 | if: failure() 35 | with: 36 | name: test-debug-artifacts 37 | path: | 38 | datasource/*/git_*_basic_test.pkr.hcl 39 | datasource/*/packer_log_git_*_basic_test.txt 40 | if-no-files-found: ignore 41 | -------------------------------------------------------------------------------- /.github/workflows/test-plugin-example.yml: -------------------------------------------------------------------------------- 1 | # This is a manually triggered action workflow. 2 | # It uses Packer at latest version to init, validate and build 3 | # an example configuration in a folder. 4 | # This action is compatible with Packer v1.7.0 or later. 5 | name: test plugin example 6 | 7 | on: 8 | workflow_dispatch: 9 | inputs: 10 | logs: 11 | description: 'Set 1 to activate full logs' 12 | required: false 13 | default: '0' 14 | 15 | jobs: 16 | build: 17 | runs-on: ubuntu-latest 18 | name: init and build example 19 | steps: 20 | - name: Checkout Repository 21 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 22 | 23 | - name: Build and Install Plugin 24 | run: make dev 25 | 26 | - name: Init 27 | uses: hashicorp/setup-packer@1aa358be5cf73883762b302a3a03abd66e75b232 # v3.1.0 28 | with: 29 | working_directory: './example' 30 | command: init 31 | 32 | - name: Validate 33 | uses: hashicorp/setup-packer@1aa358be5cf73883762b302a3a03abd66e75b232 # v3.1.0 34 | with: 35 | working_directory: './example' 36 | command: validate 37 | env: 38 | PACKER_LOG: ${{ github.event.inputs.logs }} 39 | 40 | - name: Build 41 | uses: hashicorp/setup-packer@1aa358be5cf73883762b302a3a03abd66e75b232 # v3.1.0 42 | with: 43 | working_directory: './example' 44 | command: build 45 | env: 46 | PACKER_LOG: ${{ github.event.inputs.logs }} 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | main 2 | dist/* 3 | packer-plugin-git 4 | .idea 5 | docs.zip 6 | **/packer_log*.txt 7 | **/git_*test.pkr.hcl 8 | crash.log 9 | .docs 10 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # This is an example goreleaser.yaml file with some defaults. 2 | # Make sure to check the documentation at http://goreleaser.com 3 | version: 2 4 | env: 5 | - CGO_ENABLED=0 6 | before: 7 | hooks: 8 | # We strongly recommend running tests to catch any regression before release. 9 | # Even though, this an optional step. 10 | - go test ./... 11 | # Check plugin compatibility with required version of the Packer SDK 12 | - make plugin-check 13 | builds: 14 | # A separated build to run the packer-plugins-check only once for a linux_amd64 binary 15 | - 16 | id: plugin-check 17 | mod_timestamp: '{{ .CommitTimestamp }}' 18 | flags: 19 | - -trimpath #removes all file system paths from the compiled executable 20 | ldflags: 21 | - '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= ' 22 | goos: 23 | - linux 24 | goarch: 25 | - amd64 26 | binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 27 | - 28 | mod_timestamp: '{{ .CommitTimestamp }}' 29 | flags: 30 | - -trimpath #removes all file system paths from the compiled executable 31 | ldflags: 32 | - '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= ' 33 | goos: 34 | - freebsd 35 | - windows 36 | - linux 37 | - darwin 38 | goarch: 39 | - amd64 40 | - '386' 41 | - arm 42 | - arm64 43 | ignore: 44 | - goos: darwin 45 | goarch: '386' 46 | - goos: linux 47 | goarch: amd64 48 | binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 49 | archives: 50 | - formats: [ 'zip' ] 51 | files: 52 | - none* 53 | name_template: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}' 54 | checksum: 55 | name_template: '{{ .ProjectName }}_v{{ .Version }}_SHA256SUMS' 56 | algorithm: sha256 57 | signs: 58 | - artifacts: checksum 59 | args: 60 | # if you are using this is in a GitHub action or some other automated pipeline, you 61 | # need to pass the batch flag to indicate its not interactive. 62 | - "--batch" 63 | - "--local-user" 64 | - "{{ .Env.GPG_FINGERPRINT }}" 65 | - "--output" 66 | - "${signature}" 67 | - "--detach-sign" 68 | - "${artifact}" 69 | release: 70 | # If you want to manually examine the release before its live, uncomment this line: 71 | # draft: true 72 | 73 | changelog: 74 | disable: true 75 | -------------------------------------------------------------------------------- /.web-docs/README.md: -------------------------------------------------------------------------------- 1 | The Git plugin is able to interact with Git repos through Packer. 2 | 3 | ### Installation 4 | 5 | To install this plugin, copy and paste this code into your Packer configuration, then run [`packer init`](https://www.packer.io/docs/commands/init). 6 | 7 | ```hcl 8 | packer { 9 | required_plugins { 10 | git = { 11 | version = ">= 0.6.2" 12 | source = "github.com/ethanmdavidson/git" 13 | } 14 | } 15 | } 16 | ``` 17 | 18 | Alternatively, you can use `packer plugins install` to manage installation of this plugin. 19 | 20 | ```sh 21 | $ packer plugins install github.com/ethanmdavidson/git 22 | ``` 23 | 24 | ### Manual Installation 25 | 26 | You can find pre-built binary releases of the plugin 27 | [here](https://github.com/ethanmdavidson/packer-plugin-git/releases). 28 | 29 | Or, if you prefer to build the plugin from its source 30 | code, clone [the GitHub repository](https://github.com/ethanmdavidson/packer-plugin-git) 31 | locally and run the command `make build` from the root 32 | directory. Upon successful compilation, a `packer-plugin-git` plugin 33 | binary file can be found in the root directory. 34 | 35 | Once the binary is downloaded or built, please follow the Packer 36 | documentation on 37 | [installing a plugin](https://www.packer.io/docs/extending/plugins/#installing-plugins). 38 | 39 | ### Components 40 | 41 | ### Data Sources 42 | 43 | - [git-commit](/packer/integrations/ethanmdavidson/git/latest/components/data-source/commit) - Retrieve information 44 | about a specific commit, e.g. the commit hash. 45 | - [git-repository](/packer/integrations/ethanmdavidson/git/latest/components/data-source/repository) - Retrieve information 46 | about a repository, e.g. the value of HEAD. 47 | - [git-tree](/packer/integrations/ethanmdavidson/git/latest/components/data-source/tree) - Retrieve the list of 48 | files present in a specific commit, similar to `git ls-tree -r`. 49 | 50 | -------------------------------------------------------------------------------- /.web-docs/components/data-source/commit/README.md: -------------------------------------------------------------------------------- 1 | Type: `git-commit` 2 | 3 | The commit data source is used to fetch information about a specific commit. 4 | It needs to be run inside an existing git repo. 5 | 6 | 7 | ## Required 8 | 9 | There are no required configuration fields. 10 | 11 | 12 | ## Optional 13 | 14 | - `path` (string) - The path to a directory inside your git repo. The plugin will 15 | search for a git repo, starting in this directory and walking up through 16 | parent directories. Defaults to '.' (the directory packer was executed in). 17 | 18 | - `commit_ish` (string) - A [Commit-Ish value](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefcommit-ishacommit-ishalsocommittish) 19 | (e.g. tag) pointing to the target commit object. 20 | See [go-git ResolveRevision](https://pkg.go.dev/github.com/go-git/go-git/v5#Repository.ResolveRevision) 21 | for the list of supported values. Defaults to 'HEAD'. 22 | 23 | 24 | ## Output 25 | 26 | - `hash` (string) - The SHA1 checksum or "hash" value of the selected commit. 27 | - `branches` (string) - The short names of branches at the selected commit. 28 | - `author` (string) - The author of the commit, in standard `A U Thor ` format. 29 | - `committer` (string) - The committer of the commit, in same format as author. 30 | - `timestamp` (string) - The timestamp of the commit, in RFC3339 format (e.g. `2024-01-02T09:38:19Z`). 31 | - `pgp_signature` (string) - The PGP signature attached to the commit. 32 | - `message` (string) - The commit message. 33 | - `tree_hash` (string) - The hash of the root tree of the commit. 34 | - `parent_hashes` (list[string]) - The hashes of the parent commits. 35 | 36 | 37 | ## Example Usage 38 | 39 | This example shows how a truncated commit sha can be appended 40 | to an image name, with the author in the image description. 41 | 42 | ```hcl 43 | data "git-commit" "cwd-head" { } 44 | 45 | locals { 46 | truncated_sha = substr(data.git-commit.cwd-head.hash, 0, 8) 47 | author = data.git-commit.cwd-head.author 48 | } 49 | 50 | source "googlecompute" "example" { 51 | image_name = "image-${local.truncated_sha}" 52 | image_description = "Built from a commit by ${local.author}" 53 | } 54 | 55 | build { 56 | sources = ["source.googlecompute.example"] 57 | } 58 | ``` 59 | -------------------------------------------------------------------------------- /.web-docs/components/data-source/repository/README.md: -------------------------------------------------------------------------------- 1 | Type: `git-repository` 2 | 3 | The repository data source is used to fetch information about a git repository. 4 | It needs to be run inside an existing git repo. 5 | 6 | 7 | ## Required 8 | 9 | There are no required configuration fields. 10 | 11 | 12 | ## Optional 13 | 14 | - `path` (string) - The path to a directory inside your git repo. The plugin will 15 | search for a git repo, starting in this directory and walking up through 16 | parent directories. Defaults to '.' (the directory packer was executed in). 17 | 18 | 19 | ## Output 20 | 21 | - `head` (string) - The short name of HEAD's current location. 22 | - `branches` (list[string]) - The list of branches in the repository. 23 | - `tags` (list[string]) - The list of tags in the repository. 24 | - `is_clean` (bool) - `true` if the working tree is clean, `false` otherwise. 25 | 26 | 27 | ## Example Usage 28 | 29 | This example shows how a a suffix can be added to the version number 30 | for any AMI built outside the main branch. 31 | 32 | ```hcl 33 | data "git-repository" "cwd" {} 34 | 35 | variable version { 36 | type = string 37 | } 38 | 39 | locals { 40 | onMain = data.git-repository.cwd.head == "main" 41 | version = onMain ? "${var.version}" : "${var.version}-SNAPSHOT" 42 | } 43 | 44 | source "amazon-ebs" "ami1" { 45 | ami_description = "AMI1" 46 | ami_name = "ami1-${local.version}" 47 | } 48 | ``` 49 | -------------------------------------------------------------------------------- /.web-docs/components/data-source/tree/README.md: -------------------------------------------------------------------------------- 1 | Type: `git-tree` 2 | 3 | The tree data source is used to fetch the 'tree' or list of files 4 | from a specific commit. It needs to be run inside an existing git 5 | repo. 6 | 7 | 8 | ## Required 9 | 10 | There are no required configuration fields. 11 | 12 | 13 | ## Optional 14 | 15 | - `path` (string) - The path to a directory inside your git repo. The 16 | plugin will search for a git repo, starting in this directory and walking 17 | up through parent directories. Defaults to '.' (the directory packer 18 | was execued in). 19 | 20 | - `commit_ish` (string) - A [Commit-Ish value](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefcommit-ishacommit-ishalsocommittish) 21 | (e.g. tag) pointing to the target commit object. 22 | See [go-git ResolveRevision](https://pkg.go.dev/github.com/go-git/go-git/v5#Repository.ResolveRevision) 23 | for the list of supported values. Defaults to 'HEAD'. 24 | 25 | 26 | ## Output 27 | 28 | - `hash` (string) - The SHA1 checksum or "hash" value of the selected commit. 29 | - `files` (list[string]) - The list of files present at this commit. 30 | 31 | ## Example Usage 32 | 33 | This example shows how to get the checksum of the files tracked by git. 34 | 35 | ```hcl 36 | data "git-tree" "cwd-head" { } 37 | 38 | locals { 39 | checksum = md5(join(",", sort(data.git-tree.cwd-head.files))) 40 | } 41 | ``` 42 | -------------------------------------------------------------------------------- /.web-docs/metadata.hcl: -------------------------------------------------------------------------------- 1 | # For full specification on the configuration of this file visit: 2 | # https://github.com/hashicorp/integration-template#metadata-configuration 3 | integration { 4 | name = "Git" 5 | description = "A plugin for Packer which provides access to git." 6 | identifier = "packer/ethanmdavidson/git" 7 | component { 8 | type = "data-source" 9 | name = "Commit" 10 | slug = "commit" 11 | } 12 | component { 13 | type = "data-source" 14 | name = "Repository" 15 | slug = "repository" 16 | } 17 | component { 18 | type = "data-source" 19 | name = "Tree" 20 | slug = "tree" 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /.web-docs/scripts/compile-to-webdocs.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Converts the folder name that the component documentation file 4 | # is stored in into the integration slug of the component. 5 | componentTypeFromFolderName() { 6 | if [[ "$1" = "builders" ]]; then 7 | echo "builder" 8 | elif [[ "$1" = "provisioners" ]]; then 9 | echo "provisioner" 10 | elif [[ "$1" = "post-processors" ]]; then 11 | echo "post-processor" 12 | elif [[ "$1" = "datasources" ]]; then 13 | echo "data-source" 14 | else 15 | echo "" 16 | fi 17 | } 18 | 19 | # $1: The content to adjust links 20 | # $2: The organization of the integration 21 | rewriteLinks() { 22 | local result="$1" 23 | local organization="$2" 24 | 25 | urlSegment="([^/]+)" 26 | urlAnchor="(#[^/]+)" 27 | 28 | # Rewrite Component Index Page links to the Integration root page. 29 | # 30 | # (\1) (\2) (\3) 31 | # /packer/plugins/datasources/amazon#anchor-tag--> 32 | # /packer/integrations/hashicorp/amazon#anchor-tag 33 | local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment$urlAnchor?\)" 34 | local replace="\(\/packer\/integrations\/$organization\/\2\3\)" 35 | result="$(echo "$result" | sed -E "s/$find/$replace/g")" 36 | 37 | 38 | # Rewrite Component links to the Integration component page 39 | # 40 | # (\1) (\2) (\3) (\4) 41 | # /packer/plugins/datasources/amazon/parameterstore#anchor-tag --> 42 | # /packer/integrations/{organization}/amazon/latest/components/datasources/parameterstore 43 | local find="\(\/packer\/plugins\/$urlSegment\/$urlSegment\/$urlSegment$urlAnchor?\)" 44 | local replace="\(\/packer\/integrations\/$organization\/\2\/latest\/components\/\1\/\3\4\)" 45 | result="$(echo "$result" | sed -E "s/$find/$replace/g")" 46 | 47 | # Rewrite the Component URL segment from the Packer Plugin format 48 | # to the Integrations format 49 | result="$(echo "$result" \ 50 | | sed "s/\/datasources\//\/data-source\//g" \ 51 | | sed "s/\/builders\//\/builder\//g" \ 52 | | sed "s/\/post-processors\//\/post-processor\//g" \ 53 | | sed "s/\/provisioners\//\/provisioner\//g" \ 54 | )" 55 | 56 | echo "$result" 57 | } 58 | 59 | # $1: Docs Dir 60 | # $2: Web Docs Dir 61 | # $3: Component File 62 | # $4: The org of the integration 63 | processComponentFile() { 64 | local docsDir="$1" 65 | local webDocsDir="$2" 66 | local componentFile="$3" 67 | 68 | local escapedDocsDir="$(echo "$docsDir" | sed 's/\//\\\//g' | sed 's/\./\\\./g')" 69 | local componentTypeAndSlug="$(echo "$componentFile" | sed "s/$escapedDocsDir\///g" | sed 's/\.mdx//g')" 70 | 71 | # Parse out the Component Slug & Component Type 72 | local componentSlug="$(echo "$componentTypeAndSlug" | cut -d'/' -f 2)" 73 | local componentType="$(componentTypeFromFolderName "$(echo "$componentTypeAndSlug" | cut -d'/' -f 1)")" 74 | if [[ "$componentType" = "" ]]; then 75 | echo "Failed to process '$componentFile', unexpected folder name." 76 | echo "Documentation for components must be stored in one of:" 77 | echo "builders, provisioners, post-processors, datasources" 78 | exit 1 79 | fi 80 | 81 | 82 | # Calculate the location of where this file will ultimately go 83 | local webDocsFolder="$webDocsDir/components/$componentType/$componentSlug" 84 | mkdir -p "$webDocsFolder" 85 | local webDocsFile="$webDocsFolder/README.md" 86 | local webDocsFileTmp="$webDocsFolder/README.md.tmp" 87 | 88 | # Copy over the file to its webDocsFile location 89 | cp "$componentFile" "$webDocsFile" 90 | 91 | # Remove the Header 92 | local lastMetadataLine="$(grep -n -m 2 '^\-\-\-' "$componentFile" | tail -n1 | cut -d':' -f1)" 93 | cat "$webDocsFile" | tail -n +"$(($lastMetadataLine+2))" > "$webDocsFileTmp" 94 | mv "$webDocsFileTmp" "$webDocsFile" 95 | 96 | # Remove the top H1, as this will be added automatically on the web 97 | cat "$webDocsFile" | tail -n +3 > "$webDocsFileTmp" 98 | mv "$webDocsFileTmp" "$webDocsFile" 99 | 100 | # Rewrite Links 101 | rewriteLinks "$(cat "$webDocsFile")" "$4" > "$webDocsFileTmp" 102 | mv "$webDocsFileTmp" "$webDocsFile" 103 | } 104 | 105 | # Compiles the Packer SDC compiled docs folder down 106 | # to a integrations-compliant folder (web docs) 107 | # 108 | # $1: The directory of the plugin 109 | # $2: The directory of the SDC compiled docs files 110 | # $3: The output directory to place the web-docs files 111 | # $4: The org of the integration 112 | compileWebDocs() { 113 | local docsDir="$1/$2" 114 | local webDocsDir="$1/$3" 115 | 116 | echo "Compiling MDX docs in '$2' to Markdown in '$3'..." 117 | # Create the web-docs directory if it hasn't already been created 118 | mkdir -p "$webDocsDir" 119 | 120 | # Copy the README over 121 | cp "$docsDir/README.md" "$webDocsDir/README.md" 122 | 123 | # Process all MDX component files (exclude index files, which are unsupported) 124 | for file in $(find "$docsDir" | grep "$docsDir/.*/.*\.mdx" | grep --invert-match "index.mdx"); do 125 | processComponentFile "$docsDir" "$webDocsDir" "$file" "$4" 126 | done 127 | } 128 | 129 | compileWebDocs "$1" "$2" "$3" "$4" 130 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | NAME=git 2 | BINARY=packer-plugin-${NAME} 3 | PLUGIN_FQN="$(shell grep -E '^module' = 1.7.0 6 | 7 | Under the hood, it uses [go-git](https://github.com/go-git/go-git). 8 | 9 | ## Usage 10 | 11 | Add the plugin to your packer config: 12 | 13 | ```hcl 14 | packer { 15 | required_plugins { 16 | git = { 17 | version = ">= 0.6.4" 18 | source = "github.com/ethanmdavidson/git" 19 | } 20 | } 21 | } 22 | ``` 23 | 24 | Add the data source: 25 | 26 | ```hcl 27 | data "git-commit" "example" { } 28 | ``` 29 | 30 | Now you should have access to info about the commit: 31 | 32 | ```hcl 33 | locals { 34 | hash = data.git-commit.example.hash 35 | } 36 | ``` 37 | 38 | ### Examples 39 | 40 | See [the examples directory](example) for some example code. 41 | 42 | ### Components 43 | 44 | See [the docs](docs/README.md) for a reference of all the available 45 | components and their attributes. 46 | 47 | ## Development 48 | 49 | The GNUmakefile has all the commands you need to work with this repo. 50 | The typical development flow looks something like this: 51 | 52 | 1) Make code changes, and add test cases for these changes. 53 | 2) Run `make generate` to recreate generated code. 54 | 2) Run `make dev` to build the plugin and install it locally. 55 | 3) Run `make testacc` to run the acceptance tests. If there are failures, go back to step 1. 56 | 4) Update examples in `./example` directory if necessary. 57 | 5) Run `make run-example` to test examples. 58 | 6) Once the above steps are complete: commit, push, and open a PR! 59 | 60 | For local development, you will need to install: 61 | - [Packer](https://learn.hashicorp.com/tutorials/packer/get-started-install-cli) >= 1.10.2 62 | - [Go](https://golang.org/doc/install) >= 1.21 63 | - [GNU Make](https://www.gnu.org/software/make/) 64 | 65 | Check out the [Packer docs on Developing Plugins](https://developer.hashicorp.com/packer/docs/plugins/creation) 66 | for more detailed info on plugins. 67 | 68 | -------------------------------------------------------------------------------- /common/common.go: -------------------------------------------------------------------------------- 1 | // Package common contains some logic that is shared by all datasources 2 | package common 3 | 4 | import ( 5 | "log" 6 | "path/filepath" 7 | ) 8 | 9 | func PrintOpeningRepo(path string) { 10 | absPath, err := filepath.Abs(path) 11 | if err != nil { 12 | log.Printf("Finding repository from '%s' (unable to determine absolute path, %s)\n", path, err.Error()) 13 | } else { 14 | log.Printf("Finding repository from '%s' (%s)\n", path, absPath) 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /datasource/commit/data.go: -------------------------------------------------------------------------------- 1 | // Package commit contains logic for providing commit data to Packer 2 | // 3 | //go:generate packer-sdc mapstructure-to-hcl2 -type Config,DatasourceOutput 4 | package commit 5 | 6 | import ( 7 | "log" 8 | "time" 9 | 10 | "github.com/ethanmdavidson/packer-plugin-git/common" 11 | "github.com/go-git/go-git/v5" 12 | "github.com/go-git/go-git/v5/plumbing" 13 | "github.com/hashicorp/hcl/v2/hcldec" 14 | "github.com/hashicorp/packer-plugin-sdk/hcl2helper" 15 | "github.com/hashicorp/packer-plugin-sdk/template/config" 16 | "github.com/zclconf/go-cty/cty" 17 | ) 18 | 19 | type Config struct { 20 | Path string `mapstructure:"path"` 21 | CommitIsh string `mapstructure:"commit_ish"` 22 | } 23 | 24 | type Datasource struct { 25 | config Config 26 | } 27 | 28 | type DatasourceOutput struct { 29 | Hash string `mapstructure:"hash"` 30 | Branches []string `mapstructure:"branches"` 31 | Author string `mapstructure:"author"` 32 | Committer string `mapstructure:"committer"` 33 | Timestamp string `mapstructure:"timestamp"` 34 | PGPSignature string `mapstructure:"pgp_signature"` 35 | Message string `mapstructure:"message"` 36 | TreeHash string `mapstructure:"tree_hash"` 37 | ParentHashes []string `mapstructure:"parent_hashes"` 38 | } 39 | 40 | func (d *Datasource) ConfigSpec() hcldec.ObjectSpec { 41 | return d.config.FlatMapstructure().HCL2Spec() 42 | } 43 | 44 | func (d *Datasource) Configure(raws ...interface{}) error { 45 | err := config.Decode(&d.config, nil, raws...) 46 | if err != nil { 47 | return err 48 | } 49 | if d.config.Path == "" { 50 | d.config.Path = "." 51 | } 52 | if d.config.CommitIsh == "" { 53 | d.config.CommitIsh = "HEAD" 54 | } 55 | return nil 56 | } 57 | 58 | func (d *Datasource) OutputSpec() hcldec.ObjectSpec { 59 | return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec() 60 | } 61 | 62 | func (d *Datasource) Execute() (cty.Value, error) { 63 | log.Println("Starting execution") 64 | output := DatasourceOutput{} 65 | emptyOutput := hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()) 66 | 67 | common.PrintOpeningRepo(d.config.Path) 68 | openOptions := &git.PlainOpenOptions{ 69 | DetectDotGit: true, 70 | EnableDotGitCommonDir: true, 71 | } 72 | repo, err := git.PlainOpenWithOptions(d.config.Path, openOptions) 73 | if err != nil { 74 | return emptyOutput, err 75 | } 76 | log.Println("Repo opened") 77 | 78 | hash, err := repo.ResolveRevision(plumbing.Revision(d.config.CommitIsh)) 79 | if err != nil { 80 | return emptyOutput, err 81 | } 82 | log.Printf("Hash found: '%s'\n", hash.String()) 83 | 84 | branchIter, err := repo.Branches() 85 | if err != nil { 86 | return emptyOutput, err 87 | } 88 | log.Println("Branches found") 89 | 90 | commit, err := repo.CommitObject(*hash) 91 | if err != nil { 92 | return emptyOutput, err 93 | } 94 | log.Printf("Commit found: '%s'\n", commit.String()) 95 | 96 | output.Hash = hash.String() 97 | log.Printf("output.Hash: '%s'\n", output.Hash) 98 | 99 | output.Branches = make([]string, 0) 100 | _ = branchIter.ForEach(func(ref *plumbing.Reference) error { 101 | if ref.Hash().String() == hash.String() { 102 | log.Printf("Adding branch '%s'\n", ref.Name().Short()) 103 | output.Branches = append(output.Branches, ref.Name().Short()) 104 | } else { 105 | log.Printf("Not in branch '%s' (%s)\n", ref.Name().Short(), ref.Hash().String()) 106 | } 107 | return nil 108 | }) 109 | log.Printf("len(output.Branches): '%d'\n", len(output.Branches)) 110 | 111 | output.Author = commit.Author.String() 112 | log.Printf("output.Author: '%s'\n", output.Author) 113 | 114 | output.Committer = commit.Committer.String() 115 | log.Printf("output.Committer: '%s'\n", output.Committer) 116 | 117 | output.Timestamp = commit.Committer.When.UTC().Format(time.RFC3339) 118 | log.Printf("output.Timestamp: '%s'\n", output.Timestamp) 119 | 120 | output.PGPSignature = commit.PGPSignature 121 | log.Printf("len(output.PGPSignature): '%d'\n", len(output.PGPSignature)) 122 | 123 | output.Message = commit.Message 124 | log.Printf("len(output.Message): '%d'\n", len(output.Message)) 125 | 126 | output.TreeHash = commit.TreeHash.String() 127 | log.Printf("output.TreeHash: '%s'\n", output.TreeHash) 128 | 129 | output.ParentHashes = make([]string, 0) 130 | for _, parent := range commit.ParentHashes { 131 | log.Printf("Adding parent hash: '%s'\n", parent.String()) 132 | output.ParentHashes = append(output.ParentHashes, parent.String()) 133 | } 134 | log.Printf("len(output.ParentHashes): '%d'\n", len(output.ParentHashes)) 135 | 136 | return hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()), nil 137 | } 138 | -------------------------------------------------------------------------------- /datasource/commit/data.hcl2spec.go: -------------------------------------------------------------------------------- 1 | // Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. 2 | 3 | package commit 4 | 5 | import ( 6 | "github.com/hashicorp/hcl/v2/hcldec" 7 | "github.com/zclconf/go-cty/cty" 8 | ) 9 | 10 | // FlatConfig is an auto-generated flat version of Config. 11 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 12 | type FlatConfig struct { 13 | Path *string `mapstructure:"path" cty:"path" hcl:"path"` 14 | CommitIsh *string `mapstructure:"commit_ish" cty:"commit_ish" hcl:"commit_ish"` 15 | } 16 | 17 | // FlatMapstructure returns a new FlatConfig. 18 | // FlatConfig is an auto-generated flat version of Config. 19 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 20 | func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 21 | return new(FlatConfig) 22 | } 23 | 24 | // HCL2Spec returns the hcl spec of a Config. 25 | // This spec is used by HCL to read the fields of Config. 26 | // The decoded values from this spec will then be applied to a FlatConfig. 27 | func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { 28 | s := map[string]hcldec.Spec{ 29 | "path": &hcldec.AttrSpec{Name: "path", Type: cty.String, Required: false}, 30 | "commit_ish": &hcldec.AttrSpec{Name: "commit_ish", Type: cty.String, Required: false}, 31 | } 32 | return s 33 | } 34 | 35 | // FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput. 36 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 37 | type FlatDatasourceOutput struct { 38 | Hash *string `mapstructure:"hash" cty:"hash" hcl:"hash"` 39 | Branches []string `mapstructure:"branches" cty:"branches" hcl:"branches"` 40 | Author *string `mapstructure:"author" cty:"author" hcl:"author"` 41 | Committer *string `mapstructure:"committer" cty:"committer" hcl:"committer"` 42 | Timestamp *string `mapstructure:"timestamp" cty:"timestamp" hcl:"timestamp"` 43 | PGPSignature *string `mapstructure:"pgp_signature" cty:"pgp_signature" hcl:"pgp_signature"` 44 | Message *string `mapstructure:"message" cty:"message" hcl:"message"` 45 | TreeHash *string `mapstructure:"tree_hash" cty:"tree_hash" hcl:"tree_hash"` 46 | ParentHashes []string `mapstructure:"parent_hashes" cty:"parent_hashes" hcl:"parent_hashes"` 47 | } 48 | 49 | // FlatMapstructure returns a new FlatDatasourceOutput. 50 | // FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput. 51 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 52 | func (*DatasourceOutput) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 53 | return new(FlatDatasourceOutput) 54 | } 55 | 56 | // HCL2Spec returns the hcl spec of a DatasourceOutput. 57 | // This spec is used by HCL to read the fields of DatasourceOutput. 58 | // The decoded values from this spec will then be applied to a FlatDatasourceOutput. 59 | func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec { 60 | s := map[string]hcldec.Spec{ 61 | "hash": &hcldec.AttrSpec{Name: "hash", Type: cty.String, Required: false}, 62 | "branches": &hcldec.AttrSpec{Name: "branches", Type: cty.List(cty.String), Required: false}, 63 | "author": &hcldec.AttrSpec{Name: "author", Type: cty.String, Required: false}, 64 | "committer": &hcldec.AttrSpec{Name: "committer", Type: cty.String, Required: false}, 65 | "timestamp": &hcldec.AttrSpec{Name: "timestamp", Type: cty.String, Required: false}, 66 | "pgp_signature": &hcldec.AttrSpec{Name: "pgp_signature", Type: cty.String, Required: false}, 67 | "message": &hcldec.AttrSpec{Name: "message", Type: cty.String, Required: false}, 68 | "tree_hash": &hcldec.AttrSpec{Name: "tree_hash", Type: cty.String, Required: false}, 69 | "parent_hashes": &hcldec.AttrSpec{Name: "parent_hashes", Type: cty.List(cty.String), Required: false}, 70 | } 71 | return s 72 | } 73 | -------------------------------------------------------------------------------- /datasource/commit/data_acc_test.go: -------------------------------------------------------------------------------- 1 | package commit 2 | 3 | import ( 4 | _ "embed" 5 | "fmt" 6 | "io" 7 | "os" 8 | "os/exec" 9 | "regexp" 10 | "testing" 11 | 12 | "github.com/hashicorp/packer-plugin-sdk/acctest" 13 | ) 14 | 15 | //go:embed test-fixtures/template.pkr.hcl 16 | var testDatasourceHCL2Basic string 17 | 18 | // Run with: PACKER_ACC=1 go test -count 1 -v ./datasource/commit/data_acc_test.go -timeout=120m 19 | func TestAccGitCommitDatasource(t *testing.T) { 20 | testCase := &acctest.PluginTestCase{ 21 | Name: "git_commit_basic_test", 22 | Setup: func() error { 23 | return nil 24 | }, 25 | Teardown: func() error { 26 | return nil 27 | }, 28 | Template: testDatasourceHCL2Basic, 29 | Type: "git-commit", 30 | Check: func(buildCommand *exec.Cmd, logfile string) error { 31 | if buildCommand.ProcessState != nil { 32 | if buildCommand.ProcessState.ExitCode() != 0 { 33 | return fmt.Errorf("Bad exit code. Logfile: %s", logfile) 34 | } 35 | } 36 | 37 | logs, err := os.Open(logfile) 38 | if err != nil { 39 | return fmt.Errorf("Unable find %s", logfile) 40 | } 41 | defer func(logs *os.File) { 42 | _ = logs.Close() 43 | }(logs) 44 | 45 | logsBytes, err := io.ReadAll(logs) 46 | if err != nil { 47 | return fmt.Errorf("Unable to read %s", logfile) 48 | } 49 | logsString := string(logsBytes) 50 | 51 | hashLog := "null.basic-example: hash: [0-9a-f]{5,40}" 52 | branchLog := "null.basic-example: num_branches: [0-9]*" 53 | authorLog := "null.basic-example: author: [^\\n]*<[^\\n]*>" 54 | committerLog := "null.basic-example: committer: [^\\n]*<[^\\n]*>" 55 | timestampLog := "null.basic-example: timestamp: \\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z" 56 | //Can't test pgp_signature since that isn't set on most of my commits 57 | messageLog := "null.basic-example: message: .*" 58 | treeHashLog := "null.basic-example: tree_hash: [0-9a-f]{5,40}" 59 | parentLog := "null.basic-example: first_parent: [0-9a-f]{5,40}" 60 | 61 | checkMatch(t, logsString, "hash", hashLog) 62 | checkMatch(t, logsString, "num_branches", branchLog) 63 | checkMatch(t, logsString, "author", authorLog) 64 | checkMatch(t, logsString, "committer", committerLog) 65 | checkMatch(t, logsString, "timestamp", timestampLog) 66 | checkMatch(t, logsString, "message", messageLog) 67 | checkMatch(t, logsString, "tree_hash", treeHashLog) 68 | checkMatch(t, logsString, "first_parent", parentLog) 69 | return nil 70 | }, 71 | } 72 | acctest.TestPlugin(t, testCase) 73 | } 74 | 75 | func checkMatch(test *testing.T, logs string, checkName string, regex string) { 76 | if matched, _ := regexp.MatchString(regex, logs); !matched { 77 | test.Fatalf("logs don't contain expected %s value", checkName) 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /datasource/commit/test-fixtures/template.pkr.hcl: -------------------------------------------------------------------------------- 1 | data "git-commit" "test" { 2 | path = ".." 3 | } 4 | 5 | locals { 6 | hash = data.git-commit.test.hash 7 | # if message contains a single quote, the test will fail 8 | message = replace(data.git-commit.test.message, "'", "") 9 | } 10 | 11 | source "null" "basic-example" { 12 | communicator = "none" 13 | } 14 | 15 | build { 16 | sources = [ 17 | "source.null.basic-example" 18 | ] 19 | 20 | provisioner "shell-local" { 21 | inline = [ 22 | "echo 'hash: ${local.hash}'", 23 | "echo 'num_branches: ${length(data.git-commit.test.branches)}'", 24 | "echo 'author: ${data.git-commit.test.author}'", 25 | "echo 'committer: ${data.git-commit.test.committer}'", 26 | "echo 'timestamp: ${data.git-commit.test.timestamp}'", 27 | "echo 'pgp_signature: ${data.git-commit.test.pgp_signature}'", 28 | "echo 'message: ${local.message}'", 29 | "echo 'tree_hash: ${data.git-commit.test.tree_hash}'", 30 | "echo 'first_parent: ${data.git-commit.test.parent_hashes[0]}'", 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /datasource/repository/data.go: -------------------------------------------------------------------------------- 1 | // Package repository contains logic for providing repo data to Packer 2 | // 3 | //go:generate packer-sdc mapstructure-to-hcl2 -type Config,DatasourceOutput 4 | package repository 5 | 6 | import ( 7 | "github.com/ethanmdavidson/packer-plugin-git/common" 8 | "github.com/go-git/go-git/v5" 9 | "github.com/go-git/go-git/v5/plumbing" 10 | "github.com/hashicorp/hcl/v2/hcldec" 11 | "github.com/hashicorp/packer-plugin-sdk/hcl2helper" 12 | "github.com/hashicorp/packer-plugin-sdk/template/config" 13 | "github.com/zclconf/go-cty/cty" 14 | "log" 15 | ) 16 | 17 | type Config struct { 18 | Path string `mapstructure:"path"` 19 | } 20 | 21 | type Datasource struct { 22 | config Config 23 | } 24 | 25 | type DatasourceOutput struct { 26 | Head string `mapstructure:"head"` 27 | Branches []string `mapstructure:"branches"` 28 | Tags []string `mapstructure:"tags"` 29 | IsClean bool `mapstructure:"is_clean"` 30 | } 31 | 32 | func (d *Datasource) ConfigSpec() hcldec.ObjectSpec { 33 | return d.config.FlatMapstructure().HCL2Spec() 34 | } 35 | 36 | func (d *Datasource) Configure(raws ...interface{}) error { 37 | err := config.Decode(&d.config, nil, raws...) 38 | if err != nil { 39 | return err 40 | } 41 | if d.config.Path == "" { 42 | d.config.Path = "." 43 | } 44 | return nil 45 | } 46 | 47 | func (d *Datasource) OutputSpec() hcldec.ObjectSpec { 48 | return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec() 49 | } 50 | 51 | func (d *Datasource) Execute() (cty.Value, error) { 52 | log.Println("Starting execution") 53 | output := DatasourceOutput{} 54 | emptyOutput := hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()) 55 | 56 | common.PrintOpeningRepo(d.config.Path) 57 | openOptions := &git.PlainOpenOptions{DetectDotGit: true} 58 | repo, err := git.PlainOpenWithOptions(d.config.Path, openOptions) 59 | if err != nil { 60 | return emptyOutput, err 61 | } 62 | log.Println("Repo opened") 63 | 64 | head, err := repo.Head() 65 | if err != nil { 66 | return emptyOutput, err 67 | } 68 | log.Printf("Head found: '%s'\n", head.String()) 69 | 70 | worktree, err := repo.Worktree() 71 | if err != nil { 72 | return emptyOutput, err 73 | } 74 | log.Println("Worktree found") 75 | 76 | status, err := worktree.Status() 77 | if err != nil { 78 | return emptyOutput, err 79 | } 80 | log.Printf("Worktree status found: '%s'\n", status.String()) 81 | 82 | branchIter, err := repo.Branches() 83 | if err != nil { 84 | return emptyOutput, err 85 | } 86 | log.Println("Branches found") 87 | 88 | tagIter, err := repo.Tags() 89 | if err != nil { 90 | return emptyOutput, err 91 | } 92 | log.Println("Tags found") 93 | 94 | output.Head = head.Name().Short() 95 | log.Printf("output.Head: '%s'\n", output.Head) 96 | 97 | output.IsClean = status.IsClean() 98 | log.Printf("output.IsClean: '%t'\n", output.IsClean) 99 | 100 | output.Branches = make([]string, 0) 101 | _ = branchIter.ForEach(func(reference *plumbing.Reference) error { 102 | log.Printf("Adding branch: '%s'\n", reference.Name().Short()) 103 | output.Branches = append(output.Branches, reference.Name().Short()) 104 | return nil 105 | }) 106 | log.Printf("len(output.Branches): '%d'\n", len(output.Branches)) 107 | 108 | output.Tags = make([]string, 0) 109 | _ = tagIter.ForEach(func(reference *plumbing.Reference) error { 110 | log.Printf("Adding tag: '%s'\n", reference.Name().Short()) 111 | output.Tags = append(output.Tags, reference.Name().Short()) 112 | return nil 113 | }) 114 | log.Printf("len(output.Tags): '%d'\n", len(output.Tags)) 115 | 116 | return hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()), nil 117 | } 118 | -------------------------------------------------------------------------------- /datasource/repository/data.hcl2spec.go: -------------------------------------------------------------------------------- 1 | // Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. 2 | 3 | package repository 4 | 5 | import ( 6 | "github.com/hashicorp/hcl/v2/hcldec" 7 | "github.com/zclconf/go-cty/cty" 8 | ) 9 | 10 | // FlatConfig is an auto-generated flat version of Config. 11 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 12 | type FlatConfig struct { 13 | Path *string `mapstructure:"path" cty:"path" hcl:"path"` 14 | } 15 | 16 | // FlatMapstructure returns a new FlatConfig. 17 | // FlatConfig is an auto-generated flat version of Config. 18 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 19 | func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 20 | return new(FlatConfig) 21 | } 22 | 23 | // HCL2Spec returns the hcl spec of a Config. 24 | // This spec is used by HCL to read the fields of Config. 25 | // The decoded values from this spec will then be applied to a FlatConfig. 26 | func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { 27 | s := map[string]hcldec.Spec{ 28 | "path": &hcldec.AttrSpec{Name: "path", Type: cty.String, Required: false}, 29 | } 30 | return s 31 | } 32 | 33 | // FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput. 34 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 35 | type FlatDatasourceOutput struct { 36 | Head *string `mapstructure:"head" cty:"head" hcl:"head"` 37 | Branches []string `mapstructure:"branches" cty:"branches" hcl:"branches"` 38 | Tags []string `mapstructure:"tags" cty:"tags" hcl:"tags"` 39 | IsClean *bool `mapstructure:"is_clean" cty:"is_clean" hcl:"is_clean"` 40 | } 41 | 42 | // FlatMapstructure returns a new FlatDatasourceOutput. 43 | // FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput. 44 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 45 | func (*DatasourceOutput) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 46 | return new(FlatDatasourceOutput) 47 | } 48 | 49 | // HCL2Spec returns the hcl spec of a DatasourceOutput. 50 | // This spec is used by HCL to read the fields of DatasourceOutput. 51 | // The decoded values from this spec will then be applied to a FlatDatasourceOutput. 52 | func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec { 53 | s := map[string]hcldec.Spec{ 54 | "head": &hcldec.AttrSpec{Name: "head", Type: cty.String, Required: false}, 55 | "branches": &hcldec.AttrSpec{Name: "branches", Type: cty.List(cty.String), Required: false}, 56 | "tags": &hcldec.AttrSpec{Name: "tags", Type: cty.List(cty.String), Required: false}, 57 | "is_clean": &hcldec.AttrSpec{Name: "is_clean", Type: cty.Bool, Required: false}, 58 | } 59 | return s 60 | } 61 | -------------------------------------------------------------------------------- /datasource/repository/data_acc_test.go: -------------------------------------------------------------------------------- 1 | package repository 2 | 3 | import ( 4 | _ "embed" 5 | "fmt" 6 | "io" 7 | "os" 8 | "os/exec" 9 | "regexp" 10 | "testing" 11 | 12 | "github.com/hashicorp/packer-plugin-sdk/acctest" 13 | ) 14 | 15 | //go:embed test-fixtures/template.pkr.hcl 16 | var testDatasourceHCL2Basic string 17 | 18 | // Run with: PACKER_ACC=1 go test -count 1 -v ./datasource/repository/data_acc_test.go -timeout=120m 19 | func TestAccGitRepositoryDatasource(t *testing.T) { 20 | testCase := &acctest.PluginTestCase{ 21 | Name: "git_repository_basic_test", 22 | Setup: func() error { 23 | return nil 24 | }, 25 | Teardown: func() error { 26 | return nil 27 | }, 28 | Template: testDatasourceHCL2Basic, 29 | Type: "git-repository", 30 | Check: func(buildCommand *exec.Cmd, logfile string) error { 31 | if buildCommand.ProcessState != nil { 32 | if buildCommand.ProcessState.ExitCode() != 0 { 33 | return fmt.Errorf("Bad exit code. Logfile: %s", logfile) 34 | } 35 | } 36 | 37 | logs, err := os.Open(logfile) 38 | if err != nil { 39 | return fmt.Errorf("Unable find %s", logfile) 40 | } 41 | defer func(logs *os.File) { 42 | _ = logs.Close() 43 | }(logs) 44 | 45 | logsBytes, err := io.ReadAll(logs) 46 | if err != nil { 47 | return fmt.Errorf("Unable to read %s", logfile) 48 | } 49 | logsString := string(logsBytes) 50 | 51 | headLog := "null.basic-example: head: .*" 52 | isCleanLog := "null.basic-example: is_clean: [true|false]" 53 | branchesLog := "null.basic-example: num_branches: [0-9]*" 54 | tagsLog := "null.basic-example: num_tags: [0-9]*" 55 | 56 | checkMatch(t, logsString, "head", headLog) 57 | checkMatch(t, logsString, "clean", isCleanLog) 58 | checkMatch(t, logsString, "branches", branchesLog) 59 | checkMatch(t, logsString, "tags", tagsLog) 60 | 61 | return nil 62 | }, 63 | } 64 | acctest.TestPlugin(t, testCase) 65 | } 66 | 67 | func checkMatch(test *testing.T, logs string, checkName string, regex string) { 68 | if matched, _ := regexp.MatchString(regex, logs); !matched { 69 | test.Fatalf("logs don't contain expected %s value", checkName) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /datasource/repository/test-fixtures/template.pkr.hcl: -------------------------------------------------------------------------------- 1 | data "git-repository" "test" {} 2 | 3 | source "null" "basic-example" { 4 | communicator = "none" 5 | } 6 | 7 | build { 8 | sources = [ 9 | "source.null.basic-example" 10 | ] 11 | 12 | provisioner "shell-local" { 13 | inline = [ 14 | "echo 'head: ${data.git-repository.test.head}'", 15 | "echo 'is_clean: ${data.git-repository.test.is_clean}'", 16 | "echo 'num_branches: ${length(data.git-repository.test.branches)}'", 17 | "echo 'num_tags: ${length(data.git-repository.test.tags)}'", 18 | ] 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /datasource/tree/data.go: -------------------------------------------------------------------------------- 1 | // Package tree contains logic for providing working tree data to Packer 2 | // 3 | //go:generate packer-sdc mapstructure-to-hcl2 -type Config,DatasourceOutput 4 | package tree 5 | 6 | import ( 7 | "errors" 8 | "github.com/ethanmdavidson/packer-plugin-git/common" 9 | "log" 10 | 11 | "github.com/go-git/go-git/v5" 12 | "github.com/go-git/go-git/v5/plumbing" 13 | "github.com/go-git/go-git/v5/plumbing/object" 14 | "github.com/hashicorp/hcl/v2/hcldec" 15 | "github.com/hashicorp/packer-plugin-sdk/hcl2helper" 16 | "github.com/hashicorp/packer-plugin-sdk/template/config" 17 | "github.com/zclconf/go-cty/cty" 18 | ) 19 | 20 | type Config struct { 21 | Path string `mapstructure:"path"` 22 | CommitIsh string `mapstructure:"commit_ish"` //should this be tree-ish instead? 23 | } 24 | 25 | type Datasource struct { 26 | config Config 27 | } 28 | 29 | type DatasourceOutput struct { 30 | Hash string `mapstructure:"hash"` 31 | Files []string `mapstructure:"files"` 32 | } 33 | 34 | func (d *Datasource) ConfigSpec() hcldec.ObjectSpec { 35 | return d.config.FlatMapstructure().HCL2Spec() 36 | } 37 | 38 | func (d *Datasource) Configure(raws ...interface{}) error { 39 | err := config.Decode(&d.config, nil, raws...) 40 | if err != nil { 41 | return err 42 | } 43 | if d.config.Path == "" { 44 | d.config.Path = "." 45 | } 46 | if d.config.CommitIsh == "" { 47 | d.config.CommitIsh = "HEAD" 48 | } 49 | return nil 50 | } 51 | 52 | func (d *Datasource) OutputSpec() hcldec.ObjectSpec { 53 | return (&DatasourceOutput{}).FlatMapstructure().HCL2Spec() 54 | } 55 | 56 | func (d *Datasource) Execute() (cty.Value, error) { 57 | log.Println("Starting execution") 58 | output := DatasourceOutput{} 59 | emptyOutput := hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()) 60 | 61 | common.PrintOpeningRepo(d.config.Path) 62 | openOptions := &git.PlainOpenOptions{DetectDotGit: true} 63 | repo, err := git.PlainOpenWithOptions(d.config.Path, openOptions) 64 | if err != nil { 65 | return emptyOutput, err 66 | } 67 | log.Println("Repo opened") 68 | 69 | hash, err := repo.ResolveRevision(plumbing.Revision(d.config.CommitIsh)) 70 | if err != nil { 71 | return emptyOutput, err 72 | } 73 | log.Printf("Hash found: '%s'\n", hash.String()) 74 | 75 | commit, err := repo.CommitObject(*hash) 76 | if err != nil { 77 | return emptyOutput, errors.New("couldn't find commit") 78 | } 79 | log.Printf("Commit found: '%s'\n", commit.String()) 80 | 81 | tree, err := commit.Tree() 82 | if err != nil { 83 | return emptyOutput, errors.New("couldn't find tree") 84 | } 85 | log.Println("Tree found") 86 | 87 | output.Hash = hash.String() 88 | log.Printf("output.Hash: '%s'\n", output.Hash) 89 | 90 | output.Files = make([]string, 0) 91 | _ = tree.Files().ForEach(func(file *object.File) error { 92 | if file != nil { 93 | log.Printf("Adding file: '%s'\n", file.Name) 94 | output.Files = append(output.Files, file.Name) 95 | } 96 | return nil 97 | }) 98 | log.Printf("len(output.Files): '%d'\n", len(output.Files)) 99 | 100 | return hcl2helper.HCL2ValueFromConfig(output, d.OutputSpec()), nil 101 | } 102 | -------------------------------------------------------------------------------- /datasource/tree/data.hcl2spec.go: -------------------------------------------------------------------------------- 1 | // Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. 2 | 3 | package tree 4 | 5 | import ( 6 | "github.com/hashicorp/hcl/v2/hcldec" 7 | "github.com/zclconf/go-cty/cty" 8 | ) 9 | 10 | // FlatConfig is an auto-generated flat version of Config. 11 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 12 | type FlatConfig struct { 13 | Path *string `mapstructure:"path" cty:"path" hcl:"path"` 14 | CommitIsh *string `mapstructure:"commit_ish" cty:"commit_ish" hcl:"commit_ish"` 15 | } 16 | 17 | // FlatMapstructure returns a new FlatConfig. 18 | // FlatConfig is an auto-generated flat version of Config. 19 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 20 | func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 21 | return new(FlatConfig) 22 | } 23 | 24 | // HCL2Spec returns the hcl spec of a Config. 25 | // This spec is used by HCL to read the fields of Config. 26 | // The decoded values from this spec will then be applied to a FlatConfig. 27 | func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { 28 | s := map[string]hcldec.Spec{ 29 | "path": &hcldec.AttrSpec{Name: "path", Type: cty.String, Required: false}, 30 | "commit_ish": &hcldec.AttrSpec{Name: "commit_ish", Type: cty.String, Required: false}, 31 | } 32 | return s 33 | } 34 | 35 | // FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput. 36 | // Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. 37 | type FlatDatasourceOutput struct { 38 | Hash *string `mapstructure:"hash" cty:"hash" hcl:"hash"` 39 | Files []string `mapstructure:"files" cty:"files" hcl:"files"` 40 | } 41 | 42 | // FlatMapstructure returns a new FlatDatasourceOutput. 43 | // FlatDatasourceOutput is an auto-generated flat version of DatasourceOutput. 44 | // Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. 45 | func (*DatasourceOutput) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { 46 | return new(FlatDatasourceOutput) 47 | } 48 | 49 | // HCL2Spec returns the hcl spec of a DatasourceOutput. 50 | // This spec is used by HCL to read the fields of DatasourceOutput. 51 | // The decoded values from this spec will then be applied to a FlatDatasourceOutput. 52 | func (*FlatDatasourceOutput) HCL2Spec() map[string]hcldec.Spec { 53 | s := map[string]hcldec.Spec{ 54 | "hash": &hcldec.AttrSpec{Name: "hash", Type: cty.String, Required: false}, 55 | "files": &hcldec.AttrSpec{Name: "files", Type: cty.List(cty.String), Required: false}, 56 | } 57 | return s 58 | } 59 | -------------------------------------------------------------------------------- /datasource/tree/data_acc_test.go: -------------------------------------------------------------------------------- 1 | package tree 2 | 3 | import ( 4 | _ "embed" 5 | "fmt" 6 | "io" 7 | "os" 8 | "os/exec" 9 | "regexp" 10 | "testing" 11 | 12 | "github.com/hashicorp/packer-plugin-sdk/acctest" 13 | ) 14 | 15 | //go:embed test-fixtures/template.pkr.hcl 16 | var testDatasourceHCL2Basic string 17 | 18 | // Run with: PACKER_ACC=1 go test -count 1 -v ./datasource/tree/data_acc_test.go -timeout=120m 19 | func TestAccGitTreeDatasource(t *testing.T) { 20 | testCase := &acctest.PluginTestCase{ 21 | Name: "git_tree_basic_test", 22 | Setup: func() error { 23 | return nil 24 | }, 25 | Teardown: func() error { 26 | return nil 27 | }, 28 | Template: testDatasourceHCL2Basic, 29 | Type: "git-tree", 30 | Check: func(buildCommand *exec.Cmd, logfile string) error { 31 | if buildCommand.ProcessState != nil { 32 | if buildCommand.ProcessState.ExitCode() != 0 { 33 | return fmt.Errorf("Bad exit code. Logfile: %s", logfile) 34 | } 35 | } 36 | 37 | logs, err := os.Open(logfile) 38 | if err != nil { 39 | return fmt.Errorf("Unable find %s", logfile) 40 | } 41 | defer func(logs *os.File) { 42 | _ = logs.Close() 43 | }(logs) 44 | 45 | logsBytes, err := io.ReadAll(logs) 46 | if err != nil { 47 | return fmt.Errorf("Unable to read %s", logfile) 48 | } 49 | logsString := string(logsBytes) 50 | 51 | hashLog := "null.basic-example: hash: [0-9a-f]{5,40}" 52 | countLog := "null.basic-example: fileCount: [0-9]*" 53 | namesLog := "null.basic-example: files: [^\\n]*README.*" 54 | 55 | checkMatch(t, logsString, "hash", hashLog) 56 | checkMatch(t, logsString, "fileCount", countLog) 57 | checkMatch(t, logsString, "files", namesLog) 58 | return nil 59 | }, 60 | } 61 | acctest.TestPlugin(t, testCase) 62 | } 63 | 64 | func checkMatch(test *testing.T, logs string, checkName string, regex string) { 65 | if matched, _ := regexp.MatchString(regex, logs); !matched { 66 | test.Fatalf("logs don't contain expected %s value", checkName) 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /datasource/tree/test-fixtures/template.pkr.hcl: -------------------------------------------------------------------------------- 1 | data "git-tree" "test" {} 2 | 3 | source "null" "basic-example" { 4 | communicator = "none" 5 | } 6 | 7 | locals { 8 | numFiles = length(data.git-tree.test.files) 9 | files = join(",", data.git-tree.test.files) 10 | } 11 | 12 | build { 13 | sources = [ 14 | "source.null.basic-example" 15 | ] 16 | 17 | provisioner "shell-local" { 18 | inline = [ 19 | "echo 'hash: ${data.git-tree.test.hash}'", 20 | "echo 'fileCount: ${local.numFiles}'", 21 | "echo 'files: ${local.files}'", 22 | ] 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | The Git plugin is able to interact with Git repos through Packer. 2 | 3 | ### Installation 4 | 5 | To install this plugin, copy and paste this code into your Packer configuration, then run [`packer init`](https://www.packer.io/docs/commands/init). 6 | 7 | ```hcl 8 | packer { 9 | required_plugins { 10 | git = { 11 | version = ">= 0.6.2" 12 | source = "github.com/ethanmdavidson/git" 13 | } 14 | } 15 | } 16 | ``` 17 | 18 | Alternatively, you can use `packer plugins install` to manage installation of this plugin. 19 | 20 | ```sh 21 | $ packer plugins install github.com/ethanmdavidson/git 22 | ``` 23 | 24 | ### Manual Installation 25 | 26 | You can find pre-built binary releases of the plugin 27 | [here](https://github.com/ethanmdavidson/packer-plugin-git/releases). 28 | 29 | Or, if you prefer to build the plugin from its source 30 | code, clone [the GitHub repository](https://github.com/ethanmdavidson/packer-plugin-git) 31 | locally and run the command `make build` from the root 32 | directory. Upon successful compilation, a `packer-plugin-git` plugin 33 | binary file can be found in the root directory. 34 | 35 | Once the binary is downloaded or built, please follow the Packer 36 | documentation on 37 | [installing a plugin](https://www.packer.io/docs/extending/plugins/#installing-plugins). 38 | 39 | ### Components 40 | 41 | ### Data Sources 42 | 43 | - [git-commit](/packer/integrations/ethanmdavidson/git/latest/components/data-source/commit) - Retrieve information 44 | about a specific commit, e.g. the commit hash. 45 | - [git-repository](/packer/integrations/ethanmdavidson/git/latest/components/data-source/repository) - Retrieve information 46 | about a repository, e.g. the value of HEAD. 47 | - [git-tree](/packer/integrations/ethanmdavidson/git/latest/components/data-source/tree) - Retrieve the list of 48 | files present in a specific commit, similar to `git ls-tree -r`. 49 | 50 | -------------------------------------------------------------------------------- /docs/datasources/commit.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: > 3 | The git commit data source is used to include information about 4 | a git commit in your packer template. 5 | page_title: Commit - Data Sources 6 | nav_title: Commit 7 | --- 8 | 9 | # Commit 10 | 11 | Type: `git-commit` 12 | 13 | The commit data source is used to fetch information about a specific commit. 14 | It needs to be run inside an existing git repo. 15 | 16 | 17 | ## Required 18 | 19 | There are no required configuration fields. 20 | 21 | 22 | ## Optional 23 | 24 | - `path` (string) - The path to a directory inside your git repo. The plugin will 25 | search for a git repo, starting in this directory and walking up through 26 | parent directories. Defaults to '.' (the directory packer was executed in). 27 | 28 | - `commit_ish` (string) - A [Commit-Ish value](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefcommit-ishacommit-ishalsocommittish) 29 | (e.g. tag) pointing to the target commit object. 30 | See [go-git ResolveRevision](https://pkg.go.dev/github.com/go-git/go-git/v5#Repository.ResolveRevision) 31 | for the list of supported values. Defaults to 'HEAD'. 32 | 33 | 34 | ## Output 35 | 36 | - `hash` (string) - The SHA1 checksum or "hash" value of the selected commit. 37 | - `branches` (string) - The short names of branches at the selected commit. 38 | - `author` (string) - The author of the commit, in standard `A U Thor ` format. 39 | - `committer` (string) - The committer of the commit, in same format as author. 40 | - `timestamp` (string) - The timestamp of the commit, in RFC3339 format (e.g. `2024-01-02T09:38:19Z`). 41 | - `pgp_signature` (string) - The PGP signature attached to the commit. 42 | - `message` (string) - The commit message. 43 | - `tree_hash` (string) - The hash of the root tree of the commit. 44 | - `parent_hashes` (list[string]) - The hashes of the parent commits. 45 | 46 | 47 | ## Example Usage 48 | 49 | This example shows how a truncated commit sha can be appended 50 | to an image name, with the author in the image description. 51 | 52 | ```hcl 53 | data "git-commit" "cwd-head" { } 54 | 55 | locals { 56 | truncated_sha = substr(data.git-commit.cwd-head.hash, 0, 8) 57 | author = data.git-commit.cwd-head.author 58 | } 59 | 60 | source "googlecompute" "example" { 61 | image_name = "image-${local.truncated_sha}" 62 | image_description = "Built from a commit by ${local.author}" 63 | } 64 | 65 | build { 66 | sources = ["source.googlecompute.example"] 67 | } 68 | ``` 69 | 70 | -------------------------------------------------------------------------------- /docs/datasources/repository.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: > 3 | The git repository data source is used to include information about 4 | a git repository in your packer template. 5 | page_title: Repository - Data Sources 6 | nav_title: Repository 7 | --- 8 | 9 | # Repository 10 | 11 | Type: `git-repository` 12 | 13 | The repository data source is used to fetch information about a git repository. 14 | It needs to be run inside an existing git repo. 15 | 16 | 17 | ## Required 18 | 19 | There are no required configuration fields. 20 | 21 | 22 | ## Optional 23 | 24 | - `path` (string) - The path to a directory inside your git repo. The plugin will 25 | search for a git repo, starting in this directory and walking up through 26 | parent directories. Defaults to '.' (the directory packer was executed in). 27 | 28 | 29 | ## Output 30 | 31 | - `head` (string) - The short name of HEAD's current location. 32 | - `branches` (list[string]) - The list of branches in the repository. 33 | - `tags` (list[string]) - The list of tags in the repository. 34 | - `is_clean` (bool) - `true` if the working tree is clean, `false` otherwise. 35 | 36 | 37 | ## Example Usage 38 | 39 | This example shows how a a suffix can be added to the version number 40 | for any AMI built outside the main branch. 41 | 42 | ```hcl 43 | data "git-repository" "cwd" {} 44 | 45 | variable version { 46 | type = string 47 | } 48 | 49 | locals { 50 | onMain = data.git-repository.cwd.head == "main" 51 | version = onMain ? "${var.version}" : "${var.version}-SNAPSHOT" 52 | } 53 | 54 | source "amazon-ebs" "ami1" { 55 | ami_description = "AMI1" 56 | ami_name = "ami1-${local.version}" 57 | } 58 | ``` 59 | 60 | -------------------------------------------------------------------------------- /docs/datasources/tree.mdx: -------------------------------------------------------------------------------- 1 | --- 2 | description: > 3 | The git tree data source is used to include information about 4 | a commit tree into your packer template. 5 | page_title: Tree - Data Sources 6 | nav_title: Tree 7 | --- 8 | 9 | # Tree 10 | 11 | Type: `git-tree` 12 | 13 | The tree data source is used to fetch the 'tree' or list of files 14 | from a specific commit. It needs to be run inside an existing git 15 | repo. 16 | 17 | 18 | ## Required 19 | 20 | There are no required configuration fields. 21 | 22 | 23 | ## Optional 24 | 25 | - `path` (string) - The path to a directory inside your git repo. The 26 | plugin will search for a git repo, starting in this directory and walking 27 | up through parent directories. Defaults to '.' (the directory packer 28 | was execued in). 29 | 30 | - `commit_ish` (string) - A [Commit-Ish value](https://git-scm.com/docs/gitglossary#Documentation/gitglossary.txt-aiddefcommit-ishacommit-ishalsocommittish) 31 | (e.g. tag) pointing to the target commit object. 32 | See [go-git ResolveRevision](https://pkg.go.dev/github.com/go-git/go-git/v5#Repository.ResolveRevision) 33 | for the list of supported values. Defaults to 'HEAD'. 34 | 35 | 36 | ## Output 37 | 38 | - `hash` (string) - The SHA1 checksum or "hash" value of the selected commit. 39 | - `files` (list[string]) - The list of files present at this commit. 40 | 41 | ## Example Usage 42 | 43 | This example shows how to get the checksum of the files tracked by git. 44 | 45 | ```hcl 46 | data "git-tree" "cwd-head" { } 47 | 48 | locals { 49 | checksum = md5(join(",", sort(data.git-tree.cwd-head.files))) 50 | } 51 | ``` 52 | 53 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | ## The Example Folder 2 | 3 | This folder contains a fully working example of the plugin usage. 4 | A pre-defined GitHub Action runs `packer init`, `packer validate`, 5 | and `packer build` to test this plugin with the latest version available of Packer. 6 | 7 | -------------------------------------------------------------------------------- /example/commit.pkr.hcl: -------------------------------------------------------------------------------- 1 | packer {} 2 | 3 | data "git-commit" "test" {} 4 | 5 | locals { 6 | hash = data.git-commit.test.hash 7 | # if message contains a single quote, it will mess up the echo command 8 | message = replace(data.git-commit.test.message, "'", "") 9 | branchesString = join(",", sort(data.git-commit.test.branches)) 10 | } 11 | 12 | source "null" "git-plugin-test-commit" { 13 | communicator = "none" 14 | } 15 | 16 | build { 17 | sources = [ 18 | "source.null.git-plugin-test-commit", 19 | ] 20 | provisioner "shell-local" { 21 | inline = [ 22 | "echo 'hash: ${local.hash}'", 23 | "echo 'branches: ${local.branchesString}'", 24 | "echo 'author: ${data.git-commit.test.author}'", 25 | "echo 'committer: ${data.git-commit.test.committer}'", 26 | "echo 'timestamp: ${data.git-commit.test.timestamp}'", 27 | "echo 'pgp_signature: ${data.git-commit.test.pgp_signature}'", 28 | "echo 'message: ${local.message}'", 29 | "echo 'tree_hash: ${data.git-commit.test.tree_hash}'", 30 | "echo 'first_parent: ${data.git-commit.test.parent_hashes[0]}'", 31 | ] 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /example/repository.pkr.hcl: -------------------------------------------------------------------------------- 1 | packer {} 2 | 3 | data "git-repository" "test" {} 4 | 5 | locals { 6 | branches = join(",", data.git-repository.test.branches) 7 | tags = join(",", data.git-repository.test.tags) 8 | } 9 | 10 | source "null" "git-plugin-test-repository" { 11 | communicator = "none" 12 | } 13 | 14 | build { 15 | sources = [ 16 | "source.null.git-plugin-test-repository", 17 | ] 18 | provisioner "shell-local" { 19 | inline = [ 20 | "echo 'head: ${data.git-repository.test.head}'", 21 | "echo 'is_clean: ${data.git-repository.test.is_clean}'", 22 | "echo 'branches: ${local.branches}'", 23 | "echo 'tags: ${local.tags}'", 24 | ] 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /example/tree.pkr.hcl: -------------------------------------------------------------------------------- 1 | packer {} 2 | 3 | data git-tree example {} 4 | 5 | locals { 6 | numFiles = length(data.git-tree.example.files) 7 | fileString = join(",", sort(data.git-tree.example.files)) 8 | fileChecksum = md5(local.fileString) 9 | } 10 | 11 | source "null" "git-plugin-test-tree" { 12 | communicator = "none" 13 | } 14 | 15 | build { 16 | sources = ["source.null.git-plugin-test-tree"] 17 | 18 | provisioner "shell-local" { 19 | inline = [ 20 | "echo 'numFiles: ${local.numFiles}'", 21 | "echo 'files: ${local.fileString}'", 22 | "echo 'checksum: ${local.fileChecksum}'", 23 | ] 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/ethanmdavidson/packer-plugin-git 2 | 3 | go 1.23.0 4 | 5 | require ( 6 | github.com/go-git/go-git/v5 v5.16.0 7 | github.com/hashicorp/hcl/v2 v2.23.0 8 | github.com/hashicorp/packer-plugin-sdk v0.6.1 9 | github.com/zclconf/go-cty v1.16.2 10 | ) 11 | 12 | require ( 13 | dario.cat/mergo v1.0.1 // indirect 14 | github.com/Microsoft/go-winio v0.6.2 // indirect 15 | github.com/ProtonMail/go-crypto v1.1.6 // indirect 16 | github.com/agext/levenshtein v1.2.3 // indirect 17 | github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect 18 | github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect 19 | github.com/armon/go-metrics v0.4.1 // indirect 20 | github.com/aws/aws-sdk-go v1.55.6 // indirect 21 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect 22 | github.com/cenkalti/backoff/v4 v4.3.0 // indirect 23 | github.com/cloudflare/circl v1.6.1 // indirect 24 | github.com/cyphar/filepath-securejoin v0.4.1 // indirect 25 | github.com/emirpasic/gods v1.18.1 // indirect 26 | github.com/fatih/color v1.18.0 // indirect 27 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect 28 | github.com/go-git/go-billy/v5 v5.6.2 // indirect 29 | github.com/go-jose/go-jose/v4 v4.0.5 // indirect 30 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect 31 | github.com/google/uuid v1.6.0 // indirect 32 | github.com/hashicorp/consul/api v1.31.2 // indirect 33 | github.com/hashicorp/errwrap v1.1.0 // indirect 34 | github.com/hashicorp/go-cleanhttp v0.5.2 // indirect 35 | github.com/hashicorp/go-getter/v2 v2.2.3 // indirect 36 | github.com/hashicorp/go-hclog v1.6.3 // indirect 37 | github.com/hashicorp/go-immutable-radix v1.3.1 // indirect 38 | github.com/hashicorp/go-metrics v0.5.4 // indirect 39 | github.com/hashicorp/go-multierror v1.1.1 // indirect 40 | github.com/hashicorp/go-retryablehttp v0.7.7 // indirect 41 | github.com/hashicorp/go-rootcerts v1.0.2 // indirect 42 | github.com/hashicorp/go-safetemp v1.0.0 // indirect 43 | github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 // indirect 44 | github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect 45 | github.com/hashicorp/go-sockaddr v1.0.7 // indirect 46 | github.com/hashicorp/go-version v1.7.0 // indirect 47 | github.com/hashicorp/golang-lru v1.0.2 // indirect 48 | github.com/hashicorp/hcl v1.0.0 // indirect 49 | github.com/hashicorp/serf v0.10.2 // indirect 50 | github.com/hashicorp/vault/api v1.16.0 // indirect 51 | github.com/hashicorp/yamux v0.1.2 // indirect 52 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect 53 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect 54 | github.com/jmespath/go-jmespath v0.4.0 // indirect 55 | github.com/kevinburke/ssh_config v1.2.0 // indirect 56 | github.com/klauspost/compress v1.18.0 // indirect 57 | github.com/mattn/go-colorable v0.1.14 // indirect 58 | github.com/mattn/go-isatty v0.0.20 // indirect 59 | github.com/mitchellh/go-homedir v1.1.0 // indirect 60 | github.com/mitchellh/go-testing-interface v1.14.1 // indirect 61 | github.com/mitchellh/go-wordwrap v1.0.1 // indirect 62 | github.com/mitchellh/iochan v1.0.0 // indirect 63 | github.com/mitchellh/mapstructure v1.5.0 // indirect 64 | github.com/mitchellh/reflectwalk v1.0.2 // indirect 65 | github.com/pjbgf/sha1cd v0.3.2 // indirect 66 | github.com/ryanuber/go-glob v1.0.0 // indirect 67 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect 68 | github.com/skeema/knownhosts v1.3.1 // indirect 69 | github.com/ugorji/go/codec v1.2.12 // indirect 70 | github.com/ulikunitz/xz v0.5.12 // indirect 71 | github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect 72 | github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 73 | github.com/xanzy/ssh-agent v0.3.3 // indirect 74 | golang.org/x/crypto v0.37.0 // indirect 75 | golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 // indirect 76 | golang.org/x/mod v0.24.0 // indirect 77 | golang.org/x/net v0.39.0 // indirect 78 | golang.org/x/sync v0.13.0 // indirect 79 | golang.org/x/sys v0.32.0 // indirect 80 | golang.org/x/text v0.24.0 // indirect 81 | golang.org/x/time v0.11.0 // indirect 82 | golang.org/x/tools v0.31.0 // indirect 83 | google.golang.org/protobuf v1.36.5 // indirect 84 | gopkg.in/warnings.v0 v0.1.2 // indirect 85 | ) 86 | 87 | replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.13.3 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187 88 | -------------------------------------------------------------------------------- /go.sum: -------------------------------------------------------------------------------- 1 | cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= 2 | dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= 3 | dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= 4 | github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= 5 | github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY= 6 | github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY= 7 | github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU= 8 | github.com/ProtonMail/go-crypto v1.1.6 h1:ZcV+Ropw6Qn0AX9brlQLAUXfqLBc7Bl+f/DmNxpLfdw= 9 | github.com/ProtonMail/go-crypto v1.1.6/go.mod h1:rA3QumHc/FZ8pAHreoekgiAbzpNsfQAosU5td4SnOrE= 10 | github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= 11 | github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= 12 | github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 13 | github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= 14 | github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 15 | github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= 16 | github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= 17 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8= 18 | github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4= 19 | github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= 20 | github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= 21 | github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= 22 | github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= 23 | github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= 24 | github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= 25 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio= 26 | github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 27 | github.com/aws/aws-sdk-go v1.55.6 h1:cSg4pvZ3m8dgYcgqB97MrcdjUmZ1BeMYKUxMMB89IPk= 28 | github.com/aws/aws-sdk-go v1.55.6/go.mod h1:eRwEWoyTWFMVYVQzKMNHWP5/RV4xIUGMQfXQHfHkpNU= 29 | github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= 30 | github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= 31 | github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= 32 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= 33 | github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= 34 | github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= 35 | github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= 36 | github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 37 | github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= 38 | github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= 39 | github.com/cloudflare/circl v1.6.1 h1:zqIqSPIndyBh1bjLVVDHMPpVKqp8Su/V+6MeDzzQBQ0= 40 | github.com/cloudflare/circl v1.6.1/go.mod h1:uddAzsPgqdMAYatqJ0lsjX1oECcQLIlRpzZh3pJrofs= 41 | github.com/cyphar/filepath-securejoin v0.4.1 h1:JyxxyPEaktOD+GAnqIqTf9A8tHyAG22rowi7HkoSU1s= 42 | github.com/cyphar/filepath-securejoin v0.4.1/go.mod h1:Sdj7gXlvMcPZsbhwhQ33GguGLDGQL7h7bg04C/+u9jI= 43 | github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 44 | github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 45 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= 46 | github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 47 | github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= 48 | github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= 49 | github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= 50 | github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= 51 | github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= 52 | github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= 53 | github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= 54 | github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c= 55 | github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU= 56 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= 57 | github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic= 58 | github.com/go-git/go-billy/v5 v5.6.2 h1:6Q86EsPXMa7c3YZ3aLAQsMA0VlWmy43r6FHqa/UNbRM= 59 | github.com/go-git/go-billy/v5 v5.6.2/go.mod h1:rcFC2rAsp/erv7CMz9GczHcuD0D32fWzH+MJAU+jaUU= 60 | github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4= 61 | github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII= 62 | github.com/go-git/go-git/v5 v5.16.0 h1:k3kuOEpkc0DeY7xlL6NaaNg39xdgQbtH5mwCafHO9AQ= 63 | github.com/go-git/go-git/v5 v5.16.0/go.mod h1:4Ge4alE/5gPs30F2H1esi2gPd69R0C39lolkucHBOp8= 64 | github.com/go-jose/go-jose/v4 v4.0.5 h1:M6T8+mKZl/+fNNuFHvGIzDz7BTLQPIounk/b9dw3AaE= 65 | github.com/go-jose/go-jose/v4 v4.0.5/go.mod h1:s3P1lRrkT8igV8D9OjyL4WRyHvjB6a4JSllnOrmmBOA= 66 | github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 67 | github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= 68 | github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= 69 | github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= 70 | github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= 71 | github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= 72 | github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= 73 | github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= 74 | github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= 75 | github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= 76 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 h1:f+oWsMOmNPc8JmEHVZIycC7hBoQxHH9pNKQORJNozsQ= 77 | github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8/go.mod h1:wcDNUvekVysuuOpQKo3191zZyTpiI6se1N1ULghS0sw= 78 | github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 79 | github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 80 | github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 81 | github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= 82 | github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= 83 | github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= 84 | github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= 85 | github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= 86 | github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 87 | github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= 88 | github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= 89 | github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= 90 | github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 91 | github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= 92 | github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 93 | github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 94 | github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 95 | github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= 96 | github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= 97 | github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= 98 | github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= 99 | github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= 100 | github.com/hashicorp/consul/api v1.31.2 h1:NicObVJHcCmyOIl7Z9iHPvvFrocgTYo9cITSGg0/7pw= 101 | github.com/hashicorp/consul/api v1.31.2/go.mod h1:Z8YgY0eVPukT/17ejW+l+C7zJmKwgPHtjU1q16v/Y40= 102 | github.com/hashicorp/consul/sdk v0.16.1 h1:V8TxTnImoPD5cj0U9Spl0TUxcytjcbbJeADFF07KdHg= 103 | github.com/hashicorp/consul/sdk v0.16.1/go.mod h1:fSXvwxB2hmh1FMZCNl6PwX0Q/1wdWtHJcZ7Ea5tns0s= 104 | github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 105 | github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= 106 | github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= 107 | github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= 108 | github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= 109 | github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= 110 | github.com/hashicorp/go-getter/v2 v2.2.3 h1:6CVzhT0KJQHqd9b0pK3xSP0CM/Cv+bVhk+jcaRJ2pGk= 111 | github.com/hashicorp/go-getter/v2 v2.2.3/go.mod h1:hp5Yy0GMQvwWVUmwLs3ygivz1JSLI323hdIE9J9m7TY= 112 | github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= 113 | github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= 114 | github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 115 | github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= 116 | github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= 117 | github.com/hashicorp/go-metrics v0.5.4 h1:8mmPiIJkTPPEbAiV97IxdAGNdRdaWwVap1BU6elejKY= 118 | github.com/hashicorp/go-metrics v0.5.4/go.mod h1:CG5yz4NZ/AI/aQt9Ucm/vdBnbh7fvmv4lxZ350i+QQI= 119 | github.com/hashicorp/go-msgpack v0.5.5 h1:i9R9JSrqIz0QVLz3sz+i3YJdT7TTSLcfLLzJi9aZTuI= 120 | github.com/hashicorp/go-msgpack/v2 v2.1.2 h1:4Ee8FTp834e+ewB71RDrQ0VKpyFdrKOjvYtnQ/ltVj0= 121 | github.com/hashicorp/go-msgpack/v2 v2.1.2/go.mod h1:upybraOAblm4S7rx0+jeNy+CWWhzywQsSRV5033mMu4= 122 | github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= 123 | github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= 124 | github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= 125 | github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= 126 | github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= 127 | github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= 128 | github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= 129 | github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= 130 | github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= 131 | github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9 h1:FW0YttEnUNDJ2WL9XcrrfteS1xW8u+sh4ggM8pN5isQ= 132 | github.com/hashicorp/go-secure-stdlib/parseutil v0.1.9/go.mod h1:Ll013mhdmsVDuoIXVfBtvgGJsXDYkTw1kooNcoCXuE0= 133 | github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 h1:kes8mmyCpxJsI7FTwtzRqEy9CdjCtrXrXGuOpxEA7Ts= 134 | github.com/hashicorp/go-secure-stdlib/strutil v0.1.2/go.mod h1:Gou2R9+il93BqX25LAKCLuM+y9U2T4hlwvT1yprcna4= 135 | github.com/hashicorp/go-sockaddr v1.0.7 h1:G+pTkSO01HpR5qCxg7lxfsFEZaG+C0VssTy/9dbT+Fw= 136 | github.com/hashicorp/go-sockaddr v1.0.7/go.mod h1:FZQbEYa1pxkQ7WLpyXJ6cbjpT8q0YgQaK/JakXqGyWw= 137 | github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 138 | github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= 139 | github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= 140 | github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= 141 | github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= 142 | github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= 143 | github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= 144 | github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= 145 | github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= 146 | github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= 147 | github.com/hashicorp/hcl/v2 v2.23.0 h1:Fphj1/gCylPxHutVSEOf2fBOh1VE4AuLV7+kbJf3qos= 148 | github.com/hashicorp/hcl/v2 v2.23.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= 149 | github.com/hashicorp/memberlist v0.5.2 h1:rJoNPWZ0juJBgqn48gjy59K5H4rNgvUoM1kUD7bXiuI= 150 | github.com/hashicorp/memberlist v0.5.2/go.mod h1:Ri9p/tRShbjYnpNf4FFPXG7wxEGY4Nrcn6E7jrVa//4= 151 | github.com/hashicorp/packer-plugin-sdk v0.6.1 h1:9lpdiwwqRPVk80bX+XJul5/RrxHMXOta15hT7JOsbGU= 152 | github.com/hashicorp/packer-plugin-sdk v0.6.1/go.mod h1:B6i8yIPzzFWrZW0hHdH5TLFGYlJEdgRNJnP5eXNxJU4= 153 | github.com/hashicorp/serf v0.10.2 h1:m5IORhuNSjaxeljg5DeQVDlQyVkhRIjJDimbkCa8aAc= 154 | github.com/hashicorp/serf v0.10.2/go.mod h1:T1CmSGfSeGfnfNy/w0odXQUR1rfECGd2Qdsp84DjOiY= 155 | github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4= 156 | github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA= 157 | github.com/hashicorp/yamux v0.1.2 h1:XtB8kyFOyHXYVFnwT5C3+Bdo8gArse7j2AQ0DA0Uey8= 158 | github.com/hashicorp/yamux v0.1.2/go.mod h1:C+zze2n6e/7wshOZep2A70/aQU6QBRWJO/G6FT1wIns= 159 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= 160 | github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= 161 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= 162 | github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= 163 | github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= 164 | github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= 165 | github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= 166 | github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= 167 | github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= 168 | github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= 169 | github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 170 | github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 171 | github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= 172 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= 173 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= 174 | github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= 175 | github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= 176 | github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo= 177 | github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ= 178 | github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 179 | github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= 180 | github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= 181 | github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= 182 | github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 183 | github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= 184 | github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= 185 | github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= 186 | github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= 187 | github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= 188 | github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= 189 | github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= 190 | github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= 191 | github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= 192 | github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= 193 | github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= 194 | github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 195 | github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 196 | github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= 197 | github.com/miekg/dns v1.1.56 h1:5imZaSeoRNvpM9SzWNhEcP9QliKiz20/dA2QabIGVnE= 198 | github.com/miekg/dns v1.1.56/go.mod h1:cRm6Oo2C8TY9ZS/TqsSrseAcncm74lfK5G+ikN2SWWY= 199 | github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= 200 | github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= 201 | github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= 202 | github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= 203 | github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0= 204 | github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0= 205 | github.com/mitchellh/iochan v1.0.0 h1:C+X3KsSTLFVBr/tK1eYN/vs4rJcvsiLU338UhYPJWeY= 206 | github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= 207 | github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= 208 | github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= 209 | github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= 210 | github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= 211 | github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 212 | github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= 213 | github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 214 | github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= 215 | github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 216 | github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= 217 | github.com/nywilken/go-cty v1.13.3 h1:03U99oXf3j3g9xgqAE3YGpixCjM8Mg09KZ0Ji9LzX0o= 218 | github.com/nywilken/go-cty v1.13.3/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= 219 | github.com/onsi/gomega v1.34.1 h1:EUMJIKUjM8sKjYbtxQI9A4z2o+rruxnzNvpknOXie6k= 220 | github.com/onsi/gomega v1.34.1/go.mod h1:kU1QgUvBDLXBJq618Xvm2LUX6rSAfRaFRTcdOeDLwwY= 221 | github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= 222 | github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= 223 | github.com/pjbgf/sha1cd v0.3.2 h1:a9wb0bp1oC2TGwStyn0Umc/IGKQnEgF0vVaZ8QF8eo4= 224 | github.com/pjbgf/sha1cd v0.3.2/go.mod h1:zQWigSxVmsHEZow5qaLtPYxpcKMMQpa09ixqBxuCS6A= 225 | github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 226 | github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 227 | github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= 228 | github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= 229 | github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 230 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= 231 | github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= 232 | github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= 233 | github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= 234 | github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= 235 | github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= 236 | github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= 237 | github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= 238 | github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 239 | github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= 240 | github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= 241 | github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= 242 | github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= 243 | github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= 244 | github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= 245 | github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= 246 | github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= 247 | github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= 248 | github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= 249 | github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= 250 | github.com/rogpeppe/go-internal v1.14.1/go.mod h1:MaRKkUm5W0goXpeCfT7UZI6fk/L7L7so1lCWt35ZSgc= 251 | github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= 252 | github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= 253 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= 254 | github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= 255 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN3Uc8sB6B/s6Z4t2xvBgU1htSHuq8= 256 | github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= 257 | github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= 258 | github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= 259 | github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 260 | github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= 261 | github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= 262 | github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= 263 | github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 264 | github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= 265 | github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= 266 | github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= 267 | github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= 268 | github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= 269 | github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= 270 | github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= 271 | github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= 272 | github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= 273 | github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= 274 | github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= 275 | github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= 276 | github.com/ulikunitz/xz v0.5.12 h1:37Nm15o69RwBkXM0J6A5OlE67RZTfzUxTj8fB3dfcsc= 277 | github.com/ulikunitz/xz v0.5.12/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= 278 | github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= 279 | github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= 280 | github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= 281 | github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= 282 | github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= 283 | github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw= 284 | github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= 285 | github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= 286 | golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 287 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= 288 | golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= 289 | golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= 290 | golang.org/x/crypto v0.37.0 h1:kJNSjF/Xp7kU0iB2Z+9viTPMW4EqqsrywMXLJOOsXSE= 291 | golang.org/x/crypto v0.37.0/go.mod h1:vg+k43peMZ0pUMhYmVAWysMK35e6ioLh3wB8ZCAfbVc= 292 | golang.org/x/exp v0.0.0-20250228200357-dead58393ab7 h1:aWwlzYV971S4BXRS9AmqwDLAD85ouC6X+pocatKY58c= 293 | golang.org/x/exp v0.0.0-20250228200357-dead58393ab7/go.mod h1:BHOTPb3L19zxehTsLoJXVaTktb06DFgmdW6Wb9s8jqk= 294 | golang.org/x/mod v0.24.0 h1:ZfthKaKaT4NrhGVZHO1/WDTwGES4De8KtWO0SIbNJMU= 295 | golang.org/x/mod v0.24.0/go.mod h1:IXM97Txy2VM4PJ3gI61r1YEk/gAj6zAHN3AdZt6S9Ww= 296 | golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 297 | golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 298 | golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= 299 | golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= 300 | golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= 301 | golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= 302 | golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= 303 | golang.org/x/net v0.39.0 h1:ZCu7HMWDxpXpaiKdhzIfaltL9Lp31x/3fCP11bc6/fY= 304 | golang.org/x/net v0.39.0/go.mod h1:X7NRbYVEA+ewNkCNyJ513WmMdQ3BineSwVtN2zD/d+E= 305 | golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= 306 | golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 307 | golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 308 | golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 309 | golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= 310 | golang.org/x/sync v0.13.0 h1:AauUjRAJ9OSnvULf/ARrrVywoJDy0YS2AwQ98I37610= 311 | golang.org/x/sync v0.13.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA= 312 | golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 313 | golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 314 | golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 315 | golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 316 | golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 317 | golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 318 | golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 319 | golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 320 | golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 321 | golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 322 | golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 323 | golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 324 | golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 325 | golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 326 | golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 327 | golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= 328 | golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 329 | golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 330 | golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 331 | golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 332 | golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 333 | golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 334 | golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= 335 | golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20= 336 | golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k= 337 | golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= 338 | golang.org/x/term v0.31.0 h1:erwDkOK1Msy6offm1mOgvspSkslFnIGsFnxOKoufg3o= 339 | golang.org/x/term v0.31.0/go.mod h1:R4BeIy7D95HzImkxGkTW1UQTtP54tio2RyHz7PwK0aw= 340 | golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 341 | golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= 342 | golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= 343 | golang.org/x/text v0.24.0 h1:dd5Bzh4yt5KYA8f9CJHCP4FB4D51c2c6JvN37xJJkJ0= 344 | golang.org/x/text v0.24.0/go.mod h1:L8rBsPeo2pSS+xqN0d5u2ikmjtmoJbDBT1b7nHvFCdU= 345 | golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0= 346 | golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg= 347 | golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= 348 | golang.org/x/tools v0.31.0 h1:0EedkvKDbh+qistFTd0Bcwe/YLh4vHwWEkiI0toFIBU= 349 | golang.org/x/tools v0.31.0/go.mod h1:naFTU+Cev749tSJRXJlna0T3WxKvb1kWEx15xA4SdmQ= 350 | golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= 351 | google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= 352 | google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= 353 | google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= 354 | google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= 355 | google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= 356 | google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= 357 | google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= 358 | google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= 359 | google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM= 360 | google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= 361 | gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 362 | gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 363 | gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= 364 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 365 | gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= 366 | gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= 367 | gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI= 368 | gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 369 | gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 370 | gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 371 | gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 372 | gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 373 | gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= 374 | gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= 375 | gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= 376 | gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= 377 | gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= 378 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "github.com/ethanmdavidson/packer-plugin-git/datasource/commit" 6 | "github.com/ethanmdavidson/packer-plugin-git/datasource/repository" 7 | "github.com/ethanmdavidson/packer-plugin-git/datasource/tree" 8 | "os" 9 | 10 | "github.com/hashicorp/packer-plugin-sdk/plugin" 11 | "github.com/hashicorp/packer-plugin-sdk/version" 12 | ) 13 | 14 | var ( 15 | // Version is the main version number that is being run at the moment. 16 | Version = "0.6.4" 17 | 18 | // PluginVersion is used by the plugin set to allow Packer to recognize 19 | // what version this plugin is. 20 | PluginVersion = version.NewRawVersion(Version) 21 | ) 22 | 23 | func main() { 24 | pps := plugin.NewSet() 25 | pps.RegisterDatasource("commit", new(commit.Datasource)) 26 | pps.RegisterDatasource("repository", new(repository.Datasource)) 27 | pps.RegisterDatasource("tree", new(tree.Datasource)) 28 | pps.SetVersion(PluginVersion) 29 | err := pps.Run() 30 | if err != nil { 31 | _, _ = fmt.Fprintln(os.Stderr, err.Error()) 32 | os.Exit(1) 33 | } 34 | } 35 | --------------------------------------------------------------------------------