├── .circleci └── config.yml ├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .github └── workflows │ ├── goreleaser.yml │ └── release.yml ├── .gitignore ├── .goreleaser.yml ├── .terraform-version ├── .terraform └── plugins │ └── darwin_amd64 │ └── lock.json ├── LICENSE ├── README.md ├── docs └── index.md ├── go.mod ├── main.go ├── main.tf ├── provider.go ├── resource_isValid.go └── update-provider.sh /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | # Golang CircleCI 2.0 configuration file 2 | # 3 | # Check https://circleci.com/docs/2.0/language-go/ for more details 4 | version: 2 5 | workflows: 6 | version: 2 7 | build_and_release: 8 | jobs: 9 | - dependencies: 10 | filters: 11 | branches: 12 | ignore: /.*/ 13 | tags: 14 | only: /.*/ 15 | - Linux: 16 | requires: 17 | - dependencies 18 | filters: 19 | branches: 20 | ignore: /.*/ 21 | tags: 22 | only: /.*/ 23 | - Mac: 24 | requires: 25 | - dependencies 26 | filters: 27 | branches: 28 | ignore: /.*/ 29 | tags: 30 | only: /.*/ 31 | - release: 32 | requires: 33 | - Linux 34 | - Mac 35 | context: github-releases 36 | filters: 37 | branches: 38 | ignore: /.*/ 39 | tags: 40 | only: /.*/ 41 | 42 | jobs: 43 | dependencies: 44 | docker: 45 | - image: circleci/golang:1 46 | #### TEMPLATE_NOTE: go expects specific checkout path representing url 47 | #### expecting it in the form of 48 | #### /go/src/github.com/circleci/go-tool 49 | #### /go/src/bitbucket.org/circleci/go-tool 50 | # working_directory: /go/src/github.com/rhythmictech/terraform-provider-errorcheck 51 | steps: 52 | - run: sudo chown -R circleci /go/src 53 | - restore_cache: 54 | keys: 55 | - godeps-v2 56 | - checkout 57 | - run: go get -v -t -d ./... 58 | - save_cache: 59 | key: godeps-v2 60 | paths: 61 | - "/go/pkg" 62 | - "/go/src" 63 | Linux: 64 | docker: 65 | - image: circleci/golang:1 66 | #### TEMPLATE_NOTE: go expects specific checkout path representing url 67 | #### expecting it in the form of 68 | #### /go/src/github.com/circleci/go-tool 69 | #### /go/src/bitbucket.org/circleci/go-tool 70 | # working_directory: /go/src/github.com/rhythmictech/terraform-provider-errorcheck 71 | steps: 72 | - run: sudo chown -R circleci /go/src 73 | - restore_cache: 74 | keys: 75 | - godeps-v2 76 | - checkout 77 | - run: CGO_ENABLED=0 go build -a -ldflags '-s' -o terraform-provider-errorcheck_v${CIRCLE_TAG}_linux_amd64 78 | - run: pwd && ls -la 79 | - persist_to_workspace: 80 | root: "." 81 | paths: 82 | - terraform-provider-errorcheck_v*_linux_amd64 83 | Mac: 84 | docker: 85 | - image: circleci/golang:1 86 | #### TEMPLATE_NOTE: go expects specific checkout path representing url 87 | #### expecting it in the form of 88 | #### /go/src/github.com/circleci/go-tool 89 | #### /go/src/bitbucket.org/circleci/go-tool 90 | # working_directory: /go/src/github.com/rhythmictech/terraform-provider-errorcheck 91 | steps: 92 | - run: sudo chown -R circleci /go/src 93 | - restore_cache: 94 | keys: 95 | - godeps-v2 96 | - checkout 97 | - run: GOOS=darwin GOARCH=amd64 go build -a -ldflags '-s' -o terraform-provider-errorcheck_v${CIRCLE_TAG}_darwin_amd64 98 | - run: pwd && ls -la 99 | - persist_to_workspace: 100 | root: "." 101 | paths: 102 | - terraform-provider-errorcheck_v*_darwin_amd64 103 | release: 104 | docker: 105 | - image: cibuilds/github:0.12 106 | steps: 107 | - attach_workspace: 108 | at: ./artifacts 109 | - run: 110 | name: "Publish Release on GitHub" 111 | command: > 112 | VERSION=${CIRCLE_TAG} 113 | 114 | ghr -t ${GITHUB_TOKEN} 115 | -u ${CIRCLE_PROJECT_USERNAME} 116 | -r ${CIRCLE_PROJECT_REPONAME} 117 | -c ${CIRCLE_SHA1} 118 | -n ${VERSION} 119 | -delete ${VERSION} 120 | ./artifacts/ 121 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1 2 | 3 | RUN apt-get update \ 4 | && apt-get -y install --no-install-recommends apt-utils 2>&1 5 | 6 | RUN go get -u -v \ 7 | github.com/mdempsky/gocode \ 8 | github.com/uudashr/gopkgs/cmd/gopkgs \ 9 | github.com/ramya-rao-a/go-outline \ 10 | github.com/acroca/go-symbols \ 11 | golang.org/x/tools/cmd/guru \ 12 | golang.org/x/tools/cmd/gorename \ 13 | github.com/rogpeppe/godef \ 14 | github.com/zmb3/gogetdoc \ 15 | github.com/sqs/goreturns \ 16 | golang.org/x/tools/cmd/goimports \ 17 | golang.org/x/lint/golint \ 18 | github.com/alecthomas/gometalinter \ 19 | honnef.co/go/tools/... \ 20 | github.com/golangci/golangci-lint/cmd/golangci-lint \ 21 | github.com/mgechev/revive \ 22 | github.com/derekparker/delve/cmd/dlv 2>&1 23 | 24 | # gocode-gomodpre 25 | RUN go get -x -d github.com/stamblerre/gocode 2>&1 \ 26 | && go build -o gocode-gomod github.com/stamblerre/gocode \ 27 | && mv gocode-gomod $GOPATH/bin/ 28 | 29 | # Install git, process tools, lsb-release (common in install instructions for CLIs) 30 | RUN apt-get update && apt-get -y install git procps lsb-release wget 31 | 32 | ENV SHELL /bin/bash 33 | 34 | RUN echo 'deb http://download.opensuse.org/repositories/shells:/fish:/release:/3/Debian_9.0/ /' > /etc/apt/sources.list.d/shells:fish:release:3.list 35 | RUN wget -nv https://download.opensuse.org/repositories/shells:fish:release:3/Debian_9.0/Release.key -O Release.key 36 | RUN apt-key add - < Release.key 37 | RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - && \ 38 | apt-get install -y nodejs 39 | RUN git clone https://github.com/smiller171/dotfiles.git ~/dotfiles 40 | RUN cd ~/dotfiles; ./setup.sh 41 | RUN cd; fish -c "echo test" 42 | ENV SHELL /usr/bin/fish 43 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Go", 3 | "dockerFile": "Dockerfile", 4 | // "appPort": 9000, 5 | "extensions": [ 6 | "ms-vscode.go", 7 | "-v", 8 | "your-volume-name-goes-here:/root/.vscode-remote" 9 | ], 10 | "runArgs": [ 11 | "--cap-add=SYS_PTRACE", 12 | "--security-opt", 13 | "seccomp=unconfined" 14 | ], 15 | "settings": { 16 | "go.gopath": "/go", 17 | "terminal.integrated.shell.linux": "/usr/bin/fish" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /.github/workflows/goreleaser.yml: -------------------------------------------------------------------------------- 1 | --- 2 | 3 | name: goreleaser 4 | 5 | on: 6 | push: 7 | branches: 8 | - master 9 | 10 | jobs: 11 | goreleaser: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - 15 | name: Checkout 16 | uses: actions/checkout@v2 17 | with: 18 | fetch-depth: 0 19 | - 20 | name: Set up Go 21 | uses: actions/setup-go@v2 22 | with: 23 | go-version: 1.14 24 | - 25 | name: Import GPG key 26 | id: import_gpg 27 | uses: crazy-max/ghaction-import-gpg@v2 28 | env: 29 | GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} 30 | PASSPHRASE: ${{ secrets.PASSPHRASE }} 31 | - 32 | name: Run GoReleaser 33 | uses: goreleaser/goreleaser-action@v2 34 | with: 35 | version: latest 36 | args: release --rm-dist 37 | env: 38 | GO111MODULE: auto 39 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 40 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 41 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | # curl -O \ 2 | # https://raw.githubusercontent.com/hashicorp/terraform-provider-scaffolding/master/.github/workflows/release.yml 3 | # This GitHub action can publish assets for release when a tag is created. 4 | # Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). 5 | # 6 | # This uses an action (paultyng/ghaction-import-gpg) that assumes you set your 7 | # private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` 8 | # secret. If you would rather own your own GPG handling, please fork this action 9 | # or use an alternative one for key handling. 10 | # 11 | # You will need to pass the `--batch` flag to `gpg` in your signing step 12 | # in `goreleaser` to indicate this is being used in a non-interactive mode. 13 | # 14 | name: release 15 | on: 16 | push: 17 | tags: 18 | - 'v*' 19 | jobs: 20 | goreleaser: 21 | runs-on: ubuntu-latest 22 | steps: 23 | - 24 | name: Checkout 25 | uses: actions/checkout@v2 26 | - 27 | name: Unshallow 28 | run: git fetch --prune --unshallow 29 | - 30 | name: Set up Go 31 | uses: actions/setup-go@v2 32 | with: 33 | go-version: 1.14 34 | - 35 | name: Import GPG key 36 | id: import_gpg 37 | uses: paultyng/ghaction-import-gpg@v2.1.0 38 | env: 39 | GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }} 40 | PASSPHRASE: ${{ secrets.PASSPHRASE }} 41 | - 42 | name: Run GoReleaser 43 | uses: goreleaser/goreleaser-action@v2 44 | with: 45 | version: latest 46 | args: release --rm-dist 47 | env: 48 | GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} 49 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 50 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.exe~ 4 | *.dll 5 | *.so 6 | *.dylib 7 | 8 | # Test binary, built with `go test -c` 9 | *.test 10 | 11 | # Output of the go coverage tool, specifically when used with LiteIDE 12 | *.out 13 | 14 | # Dependency directories (remove the comment below to include it) 15 | # vendor/ 16 | terraform-provider-* 17 | -------------------------------------------------------------------------------- /.goreleaser.yml: -------------------------------------------------------------------------------- 1 | # Visit https://goreleaser.com for documentation on how to customize this 2 | # behavior. 3 | before: 4 | hooks: 5 | # this is just an example and not a requirement for provider building/publishing 6 | - go mod tidy 7 | builds: 8 | - env: 9 | # goreleaser does not work with CGO, it could also complicate 10 | # usage by users in CI/CD systems like Terraform Cloud where 11 | # they are unable to install libraries. 12 | - CGO_ENABLED=0 13 | mod_timestamp: '{{ .CommitTimestamp }}' 14 | flags: 15 | - -trimpath 16 | ldflags: 17 | - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' 18 | goos: 19 | - freebsd 20 | - windows 21 | - linux 22 | - darwin 23 | goarch: 24 | - amd64 25 | - '386' 26 | - arm 27 | - arm64 28 | ignore: 29 | - goos: darwin 30 | goarch: '386' 31 | binary: '{{ .ProjectName }}_v{{ .Version }}' 32 | archives: 33 | - format: zip 34 | name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' 35 | checksum: 36 | name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' 37 | algorithm: sha256 38 | signs: 39 | - artifacts: checksum 40 | args: 41 | # if you are using this is a GitHub action or some other automated pipeline, you 42 | # need to pass the batch flag to indicate its not interactive. 43 | - "--batch" 44 | - "--local-user" 45 | - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key 46 | - "--output" 47 | - "${signature}" 48 | - "--detach-sign" 49 | - "${artifact}" 50 | release: 51 | # Visit your project's GitHub Releases page to publish this release. 52 | # draft: true 53 | changelog: 54 | skip: true 55 | -------------------------------------------------------------------------------- /.terraform-version: -------------------------------------------------------------------------------- 1 | 0.12.1 2 | -------------------------------------------------------------------------------- /.terraform/plugins/darwin_amd64/lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "errorcheck": "23f95b4d253028564ee21fa7fc4286454908e65e6008b93309666cdbdc207203" 3 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Rhythmic Technologies, Inc. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # terraform-provider-errorcheck 2 | A custom terraform provider that can be used to do complex validation during planning and validation 3 | 4 | ## **Deprecation warning:** 5 | While we intend on supporting this provider for the forseeable future, we have recently found a way to implement this as a module rather than a provider, allowing greater ease of use with the same interface. 6 | [GitHub](https://github.com/rhythmictech/terraform-terraform-errorcheck) 7 | [Terraform Registry](https://registry.terraform.io/modules/rhythmictech/errorcheck/terraform/1.0.0) 8 | 9 | 10 | ### Installation: 11 | 12 | If you want to use the script directly from this repo: 13 | `curl -sSL https://raw.githubusercontent.com/rhythmictech/terraform-provider-errorcheck/master/update-provider.sh | bash` 14 | 15 | Otherwise you can download `update-provider.sh` and run it locally 16 | 17 | ### example: 18 | code: 19 | ```terraform 20 | locals { 21 | compare = "success" 22 | testSuccess = "success" 23 | testFail = "fail" 24 | } 25 | 26 | resource "errorcheck_is_valid" "shouldMatch" { 27 | name = "check_something" 28 | test = { 29 | assert = local.compare == local.testSuccess 30 | error_message = "Your assertion is not valid" 31 | } 32 | } 33 | 34 | resource "errorcheck_is_valid" "Not_valid_if_not_match" { 35 | name = "Should not match" 36 | test = { 37 | assert = local.compare == local.testFail 38 | error_message = "Your assertion is not valid" 39 | } 40 | } 41 | 42 | ``` 43 | output: 44 | ```bash 45 | terraform validate . 46 | 47 | Error: Your assertion is not valid 48 | 49 | on main.tf line 11, in resource "errorcheck_is_valid" "Not_valid_if_not_match": 50 | 11: resource "errorcheck_is_valid" "Not_valid_if_not_match" { 51 | ``` 52 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | # terraform-provider-errorcheck Provider 2 | docs for `terraform-provider-errorcheck` 3 | 4 | ## Example Usage 5 | 6 | code: 7 | ```terraform 8 | locals { 9 | compare = "success" 10 | testSuccess = "success" 11 | testFail = "fail" 12 | } 13 | 14 | resource "errorcheck_is_valid" "shouldMatch" { 15 | name = "check_something" 16 | test = { 17 | assert = local.compare == local.testSuccess 18 | error_message = "Your assertion is not valid" 19 | } 20 | } 21 | 22 | resource "errorcheck_is_valid" "Not_valid_if_not_match" { 23 | name = "Should not match" 24 | test = { 25 | assert = local.compare == local.testFail 26 | error_message = "Your assertion is not valid" 27 | } 28 | } 29 | 30 | ``` 31 | 32 | output: 33 | 34 | ```bash 35 | terraform validate . 36 | 37 | Error: Your assertion is not valid 38 | 39 | on main.tf line 11, in resource "errorcheck_is_valid" "Not_valid_if_not_match": 40 | 11: resource "errorcheck_is_valid" "Not_valid_if_not_match" { 41 | ``` 42 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/rhythmictech/terraform-provider-errorcheck/m 2 | 3 | go 1.15 4 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hashicorp/terraform/plugin" 5 | "github.com/hashicorp/terraform/terraform" 6 | ) 7 | 8 | func main() { 9 | plugin.Serve(&plugin.ServeOpts{ 10 | ProviderFunc: func() terraform.ResourceProvider { 11 | return Provider() 12 | }, 13 | }) 14 | } 15 | -------------------------------------------------------------------------------- /main.tf: -------------------------------------------------------------------------------- 1 | locals { 2 | compare = "success" 3 | testSuccess = "success" 4 | testFail = "fail" 5 | } 6 | 7 | resource "errorcheck_is_valid" "shouldMatch" { 8 | name = "check_something" 9 | test = { 10 | assert = local.compare == local.testSuccess 11 | error_message = "Your assertion is not valid" 12 | } 13 | } 14 | 15 | resource "errorcheck_is_valid" "Not_valid_if_not_match" { 16 | name = "Should not match" 17 | test = { 18 | assert = local.compare == local.testFail 19 | error_message = "Your assertion is not valid" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /provider.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hashicorp/terraform/helper/schema" 5 | ) 6 | 7 | func Provider() *schema.Provider { 8 | return &schema.Provider{ 9 | ResourcesMap: map[string]*schema.Resource{ 10 | "errorcheck_is_valid": resourceIsValid(), 11 | }, 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /resource_isValid.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | 7 | "github.com/hashicorp/terraform/helper/schema" 8 | ) 9 | 10 | func resourceIsValid() *schema.Resource { 11 | return &schema.Resource{ 12 | Create: resourceIsValidCreate, 13 | Read: resourceIsValidRead, 14 | Update: resourceIsValidUpdate, 15 | Delete: resourceIsValidDelete, 16 | 17 | Schema: map[string]*schema.Schema{ 18 | "name": &schema.Schema{ 19 | Type: schema.TypeString, 20 | Required: true, 21 | }, 22 | "test": &schema.Schema{ 23 | Type: schema.TypeMap, 24 | Required: true, 25 | ValidateFunc: func(val interface{}, key string) (warns []string, errs []error) { 26 | v := val.(map[string]interface{}) 27 | var errorMessage = "Not Valid" 28 | 29 | // Get assertValue (string) 30 | assertValue, assertKeyExists := v["assert"] 31 | if !assertKeyExists { 32 | errs = append(errs, fmt.Errorf("'test' map must contain an 'assert' key")) 33 | return 34 | } 35 | 36 | // Parse assert value (string -> bool) 37 | assert, err := strconv.ParseBool(assertValue.(string)) 38 | if err != nil { 39 | errs = append(errs, fmt.Errorf("Your assert must be a bool: %v", assertValue)) 40 | return 41 | } 42 | 43 | // Get optional error message 44 | if x, ok := v["error_message"]; ok { 45 | errorMessage = x.(string) 46 | } 47 | 48 | // Check assertion 49 | if !assert { 50 | errs = append(errs, fmt.Errorf(errorMessage)) 51 | } 52 | return 53 | }, 54 | }, 55 | }, 56 | } 57 | } 58 | 59 | func resourceIsValidCreate(d *schema.ResourceData, m interface{}) error { 60 | name := d.Get("name").(string) 61 | test := d.Get("test").(map[string]interface{}) 62 | d.SetId(name) 63 | d.Set("name", name) 64 | d.Set("test", test) 65 | return resourceIsValidRead(d, m) 66 | } 67 | 68 | func resourceIsValidRead(d *schema.ResourceData, m interface{}) error { 69 | return nil 70 | } 71 | 72 | func resourceIsValidUpdate(d *schema.ResourceData, m interface{}) error { 73 | return resourceIsValidRead(d, m) 74 | } 75 | 76 | func resourceIsValidDelete(d *schema.ResourceData, m interface{}) error { 77 | return nil 78 | } 79 | -------------------------------------------------------------------------------- /update-provider.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | 4 | linux_plugin_dir="terraform.d/plugins/linux_amd64/" 5 | mac_plugin_dir="terraform.d/plugins/darwin_amd64" 6 | 7 | if [ -z "${1}" ] 8 | then 9 | # Default to 2.0.3 10 | version="2.0.3" 11 | else 12 | # Get specific version 13 | version="${1}" 14 | fi 15 | 16 | # Delete old versions 17 | [ -d $linux_plugin_dir ] && rm $linux_plugin_dir/* 18 | [ -d $mac_plugin_dir ] && rm $mac_plugin_dir/* 19 | 20 | # if it doesn't exist 21 | # then create plugin dir 22 | [ ! -d $linux_plugin_dir ] && mkdir -p $linux_plugin_dir 23 | [ ! -d $mac_plugin_dir ] && mkdir -p $mac_plugin_dir 24 | 25 | # Download Linux provider 26 | curl -sSL -o \ 27 | "$linux_plugin_dir/terraform-provider-errorcheck_v${version}" \ 28 | "https://github.com/rhythmictech/terraform-provider-errorcheck/releases/download/${version}/terraform-provider-errorcheck_v${version}_linux_amd64" 29 | chmod 0744 $linux_plugin_dir/* 30 | 31 | # Download Mac provider 32 | curl -sSL -o \ 33 | "$mac_plugin_dir/terraform-provider-errorcheck_v${version}" \ 34 | "https://github.com/rhythmictech/terraform-provider-errorcheck/releases/download/${version}/terraform-provider-errorcheck_v${version}_darwin_amd64" 35 | chmod 0744 $mac_plugin_dir/* 36 | --------------------------------------------------------------------------------