├── .github ├── FUNDING.yml ├── codecov.yml ├── dependabot.yml └── workflows │ ├── audit.yml │ ├── vergen.yml │ ├── vergen_git2.yml │ ├── vergen_gitcl.yml │ ├── vergen_gix.yml │ ├── vergen_lib.yml │ └── vergen_pretty.yml ├── .gitignore ├── .pants-ignore ├── .vscode └── settings.json ├── CONTRIBUTING.md ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── MIGRATING_v8_to_v9.md ├── README.md ├── scripts ├── run_all.fish ├── run_all.ps1 ├── run_build.fish ├── run_build.ps1 ├── run_clippy.fish ├── run_clippy.ps1 ├── run_code_cov.fish ├── run_code_cov.ps1 ├── run_docs.fish ├── run_docs.ps1 ├── run_test.fish └── run_test.ps1 ├── test_util ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── build.rs └── src │ ├── lib.rs │ ├── repo │ └── mod.rs │ └── utils.rs ├── vergen-git2 ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── src │ ├── git2 │ │ └── mod.rs │ └── lib.rs └── tests │ └── git_output.rs ├── vergen-gitcl ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── src │ ├── gitcl │ │ └── mod.rs │ └── lib.rs └── tests │ └── git_output.rs ├── vergen-gix ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── src │ ├── gix │ │ └── mod.rs │ └── lib.rs └── tests │ └── git_output.rs ├── vergen-lib ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs └── src │ ├── config.rs │ ├── constants.rs │ ├── emitter.rs │ ├── entries.rs │ ├── keys.rs │ ├── lib.rs │ └── utils.rs ├── vergen-pretty ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs └── src │ ├── header │ └── mod.rs │ ├── lib.rs │ ├── pretty │ ├── feature │ │ ├── color.rs │ │ ├── mod.rs │ │ ├── serde.rs │ │ └── trace.rs │ ├── mod.rs │ ├── prefix.rs │ └── suffix.rs │ └── utils.rs └── vergen ├── Cargo.toml ├── LICENSE-APACHE ├── LICENSE-MIT ├── README.md ├── build.rs ├── src ├── feature │ ├── build.rs │ ├── cargo.rs │ ├── mod.rs │ ├── rustc.rs │ └── si.rs └── lib.rs └── tests ├── build_output.rs ├── cargo_output.rs ├── rustc_output.rs └── sysinfo_output.rs /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: crazysacx -------------------------------------------------------------------------------- /.github/codecov.yml: -------------------------------------------------------------------------------- 1 | coverage: 2 | status: 3 | project: 4 | default: 5 | # basic 6 | target: 90% 7 | threshold: 10% 8 | if_ci_failed: error -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "cargo" 4 | directory: "/" 5 | schedule: 6 | interval: "daily" -------------------------------------------------------------------------------- /.github/workflows/audit.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | # Trigger the workflow on push to master or any pull request 4 | # Ignore all tags 5 | push: 6 | branches: 7 | - master 8 | - legacy/* 9 | tags-ignore: 10 | - "*" 11 | pull_request: 12 | schedule: 13 | # * is a special character in YAML so you have to quote this string 14 | - cron: "23 3 * * *" 15 | 16 | concurrency: 17 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} 18 | cancel-in-progress: true 19 | 20 | env: 21 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 22 | 23 | name: 💣 Audit 💣 24 | 25 | jobs: 26 | audit-check: 27 | runs-on: ubuntu-latest 28 | name: 💣 Audit 💣 29 | steps: 30 | - name: ✅ Checkout ✅ 31 | uses: actions/checkout@v3 32 | - name: 💣 Audit 💣 33 | id: audit 34 | uses: rustyhorde/audit-check@v1 35 | with: 36 | token: ${{ secrets.GITHUB_TOKEN }} 37 | deny: 'warnings' 38 | create_issue: 'true' -------------------------------------------------------------------------------- /.github/workflows/vergen.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_dispatch: 3 | push: 4 | branches: 5 | - master 6 | - legacy/* 7 | tags-ignore: 8 | - "*" 9 | pull_request: 10 | schedule: 11 | - cron: "13 4 * * *" 12 | 13 | env: 14 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 15 | 16 | name: 🦀 vergen 🦀 17 | 18 | jobs: 19 | rustfmt: 20 | name: 📌 Formatting 📌 21 | uses: rustyhorde/workflows/.github/workflows/rustfmt.yml@main 22 | 23 | lints-linux: 24 | name: 🕳️ Clippy (Linux) 🕳️ 25 | needs: rustfmt 26 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 27 | with: 28 | os: ubuntu-latest 29 | channel: nightly 30 | target: x86_64-unknown-linux-gnu 31 | update: true 32 | project: vergen 33 | 34 | lints-macos: 35 | name: 🕳️ Clippy (MacOS) 🕳️ 36 | needs: rustfmt 37 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 38 | with: 39 | os: macos-latest 40 | channel: nightly 41 | target: apple-darwin 42 | update: true 43 | project: vergen 44 | 45 | lints-windows: 46 | name: 🕳️ Clippy (Windows) 🕳️ 47 | needs: rustfmt 48 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 49 | with: 50 | os: windows-latest 51 | channel: nightly 52 | target: x86_64-pc-windows-gnu 53 | update: true 54 | project: vergen 55 | 56 | test-linux: 57 | name: 🧪 Test (Linux) 🧪 58 | needs: lints-linux 59 | strategy: 60 | matrix: 61 | os: [ubuntu-latest] 62 | channel: ["1.85.0", "stable", "beta", "nightly"] 63 | target: [x86_64-unknown-linux-gnu] 64 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 65 | with: 66 | os: ${{ matrix.os }} 67 | channel: ${{ matrix.channel }} 68 | target: ${{ matrix.target }} 69 | update: true 70 | project: vergen 71 | 72 | test-macos: 73 | name: 🧪 Test (MacOS) 🧪 74 | needs: lints-macos 75 | strategy: 76 | matrix: 77 | os: [macos-latest] 78 | channel: ["1.85.0", "stable", "beta", "nightly"] 79 | target: [apple-darwin] 80 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 81 | with: 82 | os: ${{ matrix.os }} 83 | channel: ${{ matrix.channel }} 84 | target: ${{ matrix.target }} 85 | update: true 86 | project: vergen 87 | 88 | test-windows-gnu: 89 | name: 🧪 Test (Windows - GNU) 🧪 90 | needs: lints-windows 91 | strategy: 92 | matrix: 93 | os: [windows-latest] 94 | channel: ["1.85.0", "stable", "beta", "nightly"] 95 | target: [x86_64-pc-windows-gnu] 96 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 97 | with: 98 | os: ${{ matrix.os }} 99 | channel: ${{ matrix.channel }} 100 | target: ${{ matrix.target }} 101 | update: true 102 | project: vergen 103 | 104 | test-windows-msvc: 105 | name: 🧪 Test (Windows - MSVC) 🧪 106 | needs: lints-windows 107 | strategy: 108 | matrix: 109 | os: [windows-latest] 110 | channel: ["1.85.0", "stable", "beta", "nightly"] 111 | target: [x86_64-pc-windows-msvc] 112 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 113 | with: 114 | os: ${{ matrix.os }} 115 | channel: ${{ matrix.channel }} 116 | target: ${{ matrix.target }} 117 | update: true 118 | project: vergen 119 | 120 | coverage-linux: 121 | name: 🧱 Coverage (Linux) 🧱 122 | needs: test-linux 123 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 124 | with: 125 | os: ubuntu-latest 126 | channel: nightly 127 | target: x86_64-unknown-linux-gnu 128 | lcov: true 129 | html: true 130 | run_cmd: ${{ vars.VERGEN_RUN_CMD }} 131 | secrets: inherit 132 | 133 | coverage-macos: 134 | name: 🧱 Coverage (MacOS) 🧱 135 | needs: test-macos 136 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 137 | with: 138 | os: macos-latest 139 | channel: nightly 140 | target: apple-darwin 141 | lcov: true 142 | html: true 143 | run_cmd: ${{ vars.VERGEN_RUN_CMD }} 144 | secrets: inherit 145 | 146 | coverage-windows: 147 | name: 🧱 Coverage (Wndows) 🧱 148 | needs: [test-windows-gnu, test-windows-msvc] 149 | strategy: 150 | matrix: 151 | target: [x86_64-pc-windows-gnu, x86_64-pc-windows-msvc] 152 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 153 | with: 154 | os: windows-latest 155 | channel: nightly 156 | target: ${{ matrix.target }} 157 | lcov: true 158 | html: true 159 | run_cmd: ${{ vars.VERGEN_RUN_CMD }} 160 | secrets: inherit 161 | 162 | call-vergen-lib: 163 | name: vergen-lib 164 | needs: [coverage-linux, coverage-macos, coverage-windows] 165 | uses: ./.github/workflows/vergen_lib.yml 166 | secrets: inherit 167 | 168 | call-vergen-gix: 169 | name: vergen-gix 170 | needs: [call-vergen-lib] 171 | uses: ./.github/workflows/vergen_gix.yml 172 | secrets: inherit 173 | 174 | call-vergen-pretty: 175 | name: vergen-pretty 176 | needs: [call-vergen-gix] 177 | uses: ./.github/workflows/vergen_pretty.yml 178 | secrets: inherit -------------------------------------------------------------------------------- /.github/workflows/vergen_git2.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | 4 | env: 5 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 6 | 7 | name: 🦀 vergen-git2 🦀 8 | 9 | jobs: 10 | rustfmt: 11 | name: 📌 Formatting 📌 12 | uses: rustyhorde/workflows/.github/workflows/rustfmt.yml@main 13 | 14 | lints-linux: 15 | name: 🕳️ Clippy (Linux) 🕳️ 16 | needs: rustfmt 17 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 18 | with: 19 | os: ubuntu-latest 20 | channel: nightly 21 | target: x86_64-unknown-linux-gnu 22 | update: true 23 | project: vergen-git2 24 | 25 | lints-macos: 26 | name: 🕳️ Clippy (MacOS) 🕳️ 27 | needs: rustfmt 28 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 29 | with: 30 | os: macos-latest 31 | channel: nightly 32 | target: apple-darwin 33 | update: true 34 | project: vergen-git2 35 | 36 | lints-windows: 37 | name: 🕳️ Clippy (Windows) 🕳️ 38 | needs: rustfmt 39 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 40 | with: 41 | os: windows-latest 42 | channel: nightly 43 | target: x86_64-pc-windows-gnu 44 | update: true 45 | project: vergen-git2 46 | 47 | test-linux: 48 | name: 🧪 Test (Linux) 🧪 49 | needs: lints-linux 50 | strategy: 51 | matrix: 52 | os: [ubuntu-latest] 53 | channel: ["1.85.0", "stable", "beta", "nightly"] 54 | target: [x86_64-unknown-linux-gnu] 55 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 56 | with: 57 | os: ${{ matrix.os }} 58 | channel: ${{ matrix.channel }} 59 | target: ${{ matrix.target }} 60 | update: true 61 | project: vergen-git2 62 | 63 | test-macos: 64 | name: 🧪 Test (MacOS) 🧪 65 | needs: lints-macos 66 | strategy: 67 | matrix: 68 | os: [macos-latest] 69 | channel: ["1.85.0", "stable", "beta", "nightly"] 70 | target: [apple-darwin] 71 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 72 | with: 73 | os: ${{ matrix.os }} 74 | channel: ${{ matrix.channel }} 75 | target: ${{ matrix.target }} 76 | update: true 77 | project: vergen-git2 78 | 79 | test-windows-gnu: 80 | name: 🧪 Test (Windows - GNU) 🧪 81 | needs: lints-windows 82 | strategy: 83 | matrix: 84 | os: [windows-latest] 85 | channel: ["1.85.0", "stable", "beta", "nightly"] 86 | target: [x86_64-pc-windows-gnu] 87 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 88 | with: 89 | os: ${{ matrix.os }} 90 | channel: ${{ matrix.channel }} 91 | target: ${{ matrix.target }} 92 | update: true 93 | project: vergen-git2 94 | 95 | test-windows-msvc: 96 | name: 🧪 Test (Windows - MSVC) 🧪 97 | needs: lints-windows 98 | strategy: 99 | matrix: 100 | os: [windows-latest] 101 | channel: ["1.85.0", "stable", "beta", "nightly"] 102 | target: [x86_64-pc-windows-msvc] 103 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 104 | with: 105 | os: ${{ matrix.os }} 106 | channel: ${{ matrix.channel }} 107 | target: ${{ matrix.target }} 108 | update: true 109 | project: vergen-git2 110 | 111 | coverage-linux: 112 | name: 🧱 Coverage (Linux) 🧱 113 | needs: test-linux 114 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 115 | with: 116 | os: ubuntu-latest 117 | channel: nightly 118 | target: x86_64-unknown-linux-gnu 119 | lcov: true 120 | html: true 121 | run_cmd: ${{ vars.VERGEN_GIT2_RUN_CMD }} 122 | secrets: inherit 123 | 124 | coverage-macos: 125 | name: 🧱 Coverage (MacOS) 🧱 126 | needs: test-macos 127 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 128 | with: 129 | os: macos-latest 130 | channel: nightly 131 | target: apple-darwin 132 | lcov: true 133 | html: true 134 | run_cmd: ${{ vars.VERGEN_GIT2_RUN_CMD }} 135 | secrets: inherit 136 | 137 | coverage-windows: 138 | name: 🧱 Coverage (Wndows) 🧱 139 | needs: [test-windows-gnu, test-windows-msvc] 140 | strategy: 141 | matrix: 142 | target: [x86_64-pc-windows-gnu, x86_64-pc-windows-msvc] 143 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 144 | with: 145 | os: windows-latest 146 | channel: nightly 147 | target: ${{ matrix.target }} 148 | lcov: true 149 | html: true 150 | run_cmd: ${{ vars.VERGEN_GIT2_RUN_CMD }} 151 | secrets: inherit -------------------------------------------------------------------------------- /.github/workflows/vergen_gitcl.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | 4 | env: 5 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 6 | 7 | name: 🦀 vergen-gitcl 🦀 8 | 9 | jobs: 10 | rustfmt: 11 | name: 📌 Formatting 📌 12 | uses: rustyhorde/workflows/.github/workflows/rustfmt.yml@main 13 | 14 | lints-linux: 15 | name: 🕳️ Clippy (Linux) 🕳️ 16 | needs: rustfmt 17 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 18 | with: 19 | os: ubuntu-latest 20 | channel: nightly 21 | target: x86_64-unknown-linux-gnu 22 | update: true 23 | project: vergen-gitcl 24 | 25 | lints-macos: 26 | name: 🕳️ Clippy (MacOS) 🕳️ 27 | needs: rustfmt 28 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 29 | with: 30 | os: macos-latest 31 | channel: nightly 32 | target: apple-darwin 33 | update: true 34 | project: vergen-gitcl 35 | 36 | lints-windows: 37 | name: 🕳️ Clippy (Windows) 🕳️ 38 | needs: rustfmt 39 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 40 | with: 41 | os: windows-latest 42 | channel: nightly 43 | target: x86_64-pc-windows-gnu 44 | update: true 45 | project: vergen-gitcl 46 | 47 | test-linux: 48 | name: 🧪 Test (Linux) 🧪 49 | needs: lints-linux 50 | strategy: 51 | matrix: 52 | os: [ubuntu-latest] 53 | channel: ["1.85.0", "stable", "beta", "nightly"] 54 | target: [x86_64-unknown-linux-gnu] 55 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 56 | with: 57 | os: ${{ matrix.os }} 58 | channel: ${{ matrix.channel }} 59 | target: ${{ matrix.target }} 60 | update: true 61 | project: vergen-gitcl 62 | 63 | test-macos: 64 | name: 🧪 Test (MacOS) 🧪 65 | needs: lints-macos 66 | strategy: 67 | matrix: 68 | os: [macos-latest] 69 | channel: ["1.85.0", "stable", "beta", "nightly"] 70 | target: [apple-darwin] 71 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 72 | with: 73 | os: ${{ matrix.os }} 74 | channel: ${{ matrix.channel }} 75 | target: ${{ matrix.target }} 76 | update: true 77 | project: vergen-gitcl 78 | 79 | test-windows-gnu: 80 | name: 🧪 Test (Windows - GNU) 🧪 81 | needs: lints-windows 82 | strategy: 83 | matrix: 84 | os: [windows-latest] 85 | channel: ["1.85.0", "stable", "beta", "nightly"] 86 | target: [x86_64-pc-windows-gnu] 87 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 88 | with: 89 | os: ${{ matrix.os }} 90 | channel: ${{ matrix.channel }} 91 | target: ${{ matrix.target }} 92 | update: true 93 | project: vergen-gitcl 94 | 95 | test-windows-msvc: 96 | name: 🧪 Test (Windows - MSVC) 🧪 97 | needs: lints-windows 98 | strategy: 99 | matrix: 100 | os: [windows-latest] 101 | channel: ["1.85.0", "stable", "beta", "nightly"] 102 | target: [x86_64-pc-windows-msvc] 103 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 104 | with: 105 | os: ${{ matrix.os }} 106 | channel: ${{ matrix.channel }} 107 | target: ${{ matrix.target }} 108 | update: true 109 | project: vergen-gitcl 110 | 111 | coverage-linux: 112 | name: 🧱 Coverage (Linux) 🧱 113 | needs: test-linux 114 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 115 | with: 116 | os: ubuntu-latest 117 | channel: nightly 118 | target: x86_64-unknown-linux-gnu 119 | lcov: true 120 | html: true 121 | run_cmd: ${{ vars.VERGEN_GITCL_RUN_CMD }} 122 | secrets: inherit 123 | 124 | coverage-macos: 125 | name: 🧱 Coverage (MacOS) 🧱 126 | needs: test-macos 127 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 128 | with: 129 | os: macos-latest 130 | channel: nightly 131 | target: apple-darwin 132 | lcov: true 133 | html: true 134 | run_cmd: ${{ vars.VERGEN_GITCL_RUN_CMD }} 135 | secrets: inherit 136 | 137 | coverage-windows: 138 | name: 🧱 Coverage (Wndows) 🧱 139 | needs: [test-windows-gnu, test-windows-msvc] 140 | strategy: 141 | matrix: 142 | target: [x86_64-pc-windows-gnu, x86_64-pc-windows-msvc] 143 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 144 | with: 145 | os: windows-latest 146 | channel: nightly 147 | target: ${{ matrix.target }} 148 | lcov: true 149 | html: true 150 | run_cmd: ${{ vars.VERGEN_GITCL_RUN_CMD }} 151 | secrets: inherit -------------------------------------------------------------------------------- /.github/workflows/vergen_gix.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | 4 | env: 5 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 6 | 7 | name: 🦀 vergen-gix 🦀 8 | 9 | jobs: 10 | rustfmt: 11 | name: 📌 Formatting 📌 12 | uses: rustyhorde/workflows/.github/workflows/rustfmt.yml@main 13 | 14 | lints-linux: 15 | name: 🕳️ Clippy (Linux) 🕳️ 16 | needs: rustfmt 17 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 18 | with: 19 | os: ubuntu-latest 20 | channel: nightly 21 | target: x86_64-unknown-linux-gnu 22 | update: true 23 | project: vergen-gix 24 | 25 | lints-macos: 26 | name: 🕳️ Clippy (MacOS) 🕳️ 27 | needs: rustfmt 28 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 29 | with: 30 | os: macos-latest 31 | channel: nightly 32 | target: apple-darwin 33 | update: true 34 | project: vergen-gix 35 | 36 | lints-windows: 37 | name: 🕳️ Clippy (Windows) 🕳️ 38 | needs: rustfmt 39 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 40 | with: 41 | os: windows-latest 42 | channel: nightly 43 | target: x86_64-pc-windows-gnu 44 | update: true 45 | project: vergen-gix 46 | 47 | test-linux: 48 | name: 🧪 Test (Linux) 🧪 49 | needs: lints-linux 50 | strategy: 51 | matrix: 52 | os: [ubuntu-latest] 53 | channel: ["1.85.0", "stable", "beta", "nightly"] 54 | target: [x86_64-unknown-linux-gnu] 55 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 56 | with: 57 | os: ${{ matrix.os }} 58 | channel: ${{ matrix.channel }} 59 | target: ${{ matrix.target }} 60 | update: true 61 | project: vergen-gix 62 | 63 | test-macos: 64 | name: 🧪 Test (MacOS) 🧪 65 | needs: lints-macos 66 | strategy: 67 | matrix: 68 | os: [macos-latest] 69 | channel: ["1.85.0", "stable", "beta", "nightly"] 70 | target: [apple-darwin] 71 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 72 | with: 73 | os: ${{ matrix.os }} 74 | channel: ${{ matrix.channel }} 75 | target: ${{ matrix.target }} 76 | update: true 77 | project: vergen-gix 78 | 79 | test-windows-gnu: 80 | name: 🧪 Test (Windows - GNU) 🧪 81 | needs: lints-windows 82 | strategy: 83 | matrix: 84 | os: [windows-latest] 85 | channel: ["1.85.0", "stable", "beta", "nightly"] 86 | target: [x86_64-pc-windows-gnu] 87 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 88 | with: 89 | os: ${{ matrix.os }} 90 | channel: ${{ matrix.channel }} 91 | target: ${{ matrix.target }} 92 | update: true 93 | project: vergen-gix 94 | 95 | test-windows-msvc: 96 | name: 🧪 Test (Windows - MSVC) 🧪 97 | needs: lints-windows 98 | strategy: 99 | matrix: 100 | os: [windows-latest] 101 | channel: ["1.85.0", "stable", "beta", "nightly"] 102 | target: [x86_64-pc-windows-msvc] 103 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 104 | with: 105 | os: ${{ matrix.os }} 106 | channel: ${{ matrix.channel }} 107 | target: ${{ matrix.target }} 108 | update: true 109 | project: vergen-gix 110 | 111 | coverage-linux: 112 | name: 🧱 Coverage (Linux) 🧱 113 | needs: test-linux 114 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 115 | with: 116 | os: ubuntu-latest 117 | channel: nightly 118 | target: x86_64-unknown-linux-gnu 119 | lcov: true 120 | html: true 121 | run_cmd: ${{ vars.VERGEN_GIX_RUN_CMD }} 122 | secrets: inherit 123 | 124 | coverage-macos: 125 | name: 🧱 Coverage (MacOS) 🧱 126 | needs: test-macos 127 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 128 | with: 129 | os: macos-latest 130 | channel: nightly 131 | target: apple-darwin 132 | lcov: true 133 | html: true 134 | run_cmd: ${{ vars.VERGEN_GIX_RUN_CMD }} 135 | secrets: inherit 136 | 137 | coverage-windows: 138 | name: 🧱 Coverage (Wndows) 🧱 139 | needs: [test-windows-gnu, test-windows-msvc] 140 | strategy: 141 | matrix: 142 | target: [x86_64-pc-windows-gnu, x86_64-pc-windows-msvc] 143 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 144 | with: 145 | os: windows-latest 146 | channel: nightly 147 | target: ${{ matrix.target }} 148 | lcov: true 149 | html: true 150 | run_cmd: ${{ vars.VERGEN_GIX_RUN_CMD }} 151 | secrets: inherit -------------------------------------------------------------------------------- /.github/workflows/vergen_lib.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | 4 | env: 5 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 6 | 7 | name: 🦀 vergen-lib 🦀 8 | 9 | jobs: 10 | rustfmt: 11 | name: 📌 Formatting 📌 12 | uses: rustyhorde/workflows/.github/workflows/rustfmt.yml@main 13 | 14 | lints-linux: 15 | name: 🕳️ Clippy (Linux) 🕳️ 16 | needs: rustfmt 17 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 18 | with: 19 | os: ubuntu-latest 20 | channel: nightly 21 | target: x86_64-unknown-linux-gnu 22 | update: true 23 | project: vergen-lib 24 | 25 | lints-macos: 26 | name: 🕳️ Clippy (MacOS) 🕳️ 27 | needs: rustfmt 28 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 29 | with: 30 | os: macos-latest 31 | channel: nightly 32 | target: apple-darwin 33 | update: true 34 | project: vergen-lib 35 | 36 | lints-windows: 37 | name: 🕳️ Clippy (Windows) 🕳️ 38 | needs: rustfmt 39 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 40 | with: 41 | os: windows-latest 42 | channel: nightly 43 | target: x86_64-pc-windows-gnu 44 | update: true 45 | project: vergen-lib 46 | 47 | test-linux: 48 | name: 🧪 Test (Linux) 🧪 49 | needs: lints-linux 50 | strategy: 51 | matrix: 52 | os: [ubuntu-latest] 53 | channel: ["1.85.0", "stable", "beta", "nightly"] 54 | target: [x86_64-unknown-linux-gnu] 55 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 56 | with: 57 | os: ${{ matrix.os }} 58 | channel: ${{ matrix.channel }} 59 | target: ${{ matrix.target }} 60 | update: true 61 | project: vergen-lib 62 | 63 | test-macos: 64 | name: 🧪 Test (MacOS) 🧪 65 | needs: lints-macos 66 | strategy: 67 | matrix: 68 | os: [macos-latest] 69 | channel: ["1.85.0", "stable", "beta", "nightly"] 70 | target: [apple-darwin] 71 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 72 | with: 73 | os: ${{ matrix.os }} 74 | channel: ${{ matrix.channel }} 75 | target: ${{ matrix.target }} 76 | update: true 77 | project: vergen-lib 78 | 79 | test-windows-gnu: 80 | name: 🧪 Test (Windows - GNU) 🧪 81 | needs: lints-windows 82 | strategy: 83 | matrix: 84 | os: [windows-latest] 85 | channel: ["1.85.0", "stable", "beta", "nightly"] 86 | target: [x86_64-pc-windows-gnu] 87 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 88 | with: 89 | os: ${{ matrix.os }} 90 | channel: ${{ matrix.channel }} 91 | target: ${{ matrix.target }} 92 | update: true 93 | project: vergen-lib 94 | 95 | test-windows-msvc: 96 | name: 🧪 Test (Windows - MSVC) 🧪 97 | needs: lints-windows 98 | strategy: 99 | matrix: 100 | os: [windows-latest] 101 | channel: ["1.85.0", "stable", "beta", "nightly"] 102 | target: [x86_64-pc-windows-msvc] 103 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 104 | with: 105 | os: ${{ matrix.os }} 106 | channel: ${{ matrix.channel }} 107 | target: ${{ matrix.target }} 108 | update: true 109 | project: vergen-lib 110 | 111 | coverage-linux: 112 | name: 🧱 Coverage (Linux) 🧱 113 | needs: test-linux 114 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 115 | with: 116 | os: ubuntu-latest 117 | channel: nightly 118 | target: x86_64-unknown-linux-gnu 119 | lcov: true 120 | html: true 121 | run_cmd: ${{ vars.VERGEN_LIB_RUN_CMD }} 122 | secrets: inherit 123 | 124 | coverage-macos: 125 | name: 🧱 Coverage (MacOS) 🧱 126 | needs: test-macos 127 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 128 | with: 129 | os: macos-latest 130 | channel: nightly 131 | target: apple-darwin 132 | lcov: true 133 | html: true 134 | run_cmd: ${{ vars.VERGEN_LIB_RUN_CMD }} 135 | secrets: inherit 136 | 137 | coverage-windows: 138 | name: 🧱 Coverage (Wndows) 🧱 139 | needs: [test-windows-gnu, test-windows-msvc] 140 | strategy: 141 | matrix: 142 | target: [x86_64-pc-windows-gnu, x86_64-pc-windows-msvc] 143 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 144 | with: 145 | os: windows-latest 146 | channel: nightly 147 | target: ${{ matrix.target }} 148 | lcov: true 149 | html: true 150 | run_cmd: ${{ vars.VERGEN_LIB_RUN_CMD }} 151 | secrets: inherit -------------------------------------------------------------------------------- /.github/workflows/vergen_pretty.yml: -------------------------------------------------------------------------------- 1 | on: 2 | workflow_call: 3 | 4 | env: 5 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} 6 | 7 | name: 🦀 vergen-pretty 🦀 8 | 9 | jobs: 10 | rustfmt: 11 | name: 📌 Formatting 📌 12 | uses: rustyhorde/workflows/.github/workflows/rustfmt.yml@main 13 | 14 | lints-linux: 15 | name: 🕳️ Clippy (Linux) 🕳️ 16 | needs: rustfmt 17 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 18 | with: 19 | os: ubuntu-latest 20 | channel: nightly 21 | target: x86_64-unknown-linux-gnu 22 | update: true 23 | project: vergen-pretty 24 | 25 | lints-macos: 26 | name: 🕳️ Clippy (MacOS) 🕳️ 27 | needs: rustfmt 28 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 29 | with: 30 | os: macos-latest 31 | channel: nightly 32 | target: apple-darwin 33 | update: true 34 | project: vergen-pretty 35 | 36 | lints-windows: 37 | name: 🕳️ Clippy (Windows) 🕳️ 38 | needs: rustfmt 39 | uses: rustyhorde/workflows/.github/workflows/clippy-all-features.yml@main 40 | with: 41 | os: windows-latest 42 | channel: nightly 43 | target: x86_64-pc-windows-gnu 44 | update: true 45 | project: vergen-pretty 46 | 47 | test-linux: 48 | name: 🧪 Test (Linux) 🧪 49 | needs: lints-linux 50 | strategy: 51 | matrix: 52 | os: [ubuntu-latest] 53 | channel: ["1.85.0", "stable", "beta", "nightly"] 54 | target: [x86_64-unknown-linux-gnu] 55 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 56 | with: 57 | os: ${{ matrix.os }} 58 | channel: ${{ matrix.channel }} 59 | target: ${{ matrix.target }} 60 | update: true 61 | project: vergen-pretty 62 | 63 | test-macos: 64 | name: 🧪 Test (MacOS) 🧪 65 | needs: lints-macos 66 | strategy: 67 | matrix: 68 | os: [macos-latest] 69 | channel: ["1.85.0", "stable", "beta", "nightly"] 70 | target: [apple-darwin] 71 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 72 | with: 73 | os: ${{ matrix.os }} 74 | channel: ${{ matrix.channel }} 75 | target: ${{ matrix.target }} 76 | update: true 77 | project: vergen-pretty 78 | 79 | test-windows-gnu: 80 | name: 🧪 Test (Windows - GNU) 🧪 81 | needs: lints-windows 82 | strategy: 83 | matrix: 84 | os: [windows-latest] 85 | channel: ["1.85.0", "stable", "beta", "nightly"] 86 | target: [x86_64-pc-windows-gnu] 87 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 88 | with: 89 | os: ${{ matrix.os }} 90 | channel: ${{ matrix.channel }} 91 | target: ${{ matrix.target }} 92 | update: true 93 | project: vergen-pretty 94 | 95 | test-windows-msvc: 96 | name: 🧪 Test (Windows - MSVC) 🧪 97 | needs: lints-windows 98 | strategy: 99 | matrix: 100 | os: [windows-latest] 101 | channel: ["1.85.0", "stable", "beta", "nightly"] 102 | target: [x86_64-pc-windows-msvc] 103 | uses: rustyhorde/workflows/.github/workflows/test-all-features.yml@main 104 | with: 105 | os: ${{ matrix.os }} 106 | channel: ${{ matrix.channel }} 107 | target: ${{ matrix.target }} 108 | update: true 109 | project: vergen-pretty 110 | 111 | coverage-linux: 112 | name: 🧱 Coverage (Linux) 🧱 113 | needs: test-linux 114 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 115 | with: 116 | os: ubuntu-latest 117 | channel: nightly 118 | target: x86_64-unknown-linux-gnu 119 | lcov: true 120 | html: true 121 | run_cmd: ${{ vars.VERGEN_PRETTY_RUN_CMD }} 122 | secrets: inherit 123 | 124 | coverage-macos: 125 | name: 🧱 Coverage (MacOS) 🧱 126 | needs: test-macos 127 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 128 | with: 129 | os: macos-latest 130 | channel: nightly 131 | target: apple-darwin 132 | lcov: true 133 | html: true 134 | run_cmd: ${{ vars.VERGEN_PRETTY_RUN_CMD }} 135 | secrets: inherit 136 | 137 | coverage-windows: 138 | name: 🧱 Coverage (Wndows) 🧱 139 | needs: [test-windows-gnu, test-windows-msvc] 140 | strategy: 141 | matrix: 142 | target: [x86_64-pc-windows-gnu, x86_64-pc-windows-msvc] 143 | uses: rustyhorde/workflows/.github/workflows/coverage.yml@main 144 | with: 145 | os: windows-latest 146 | channel: nightly 147 | target: ${{ matrix.target }} 148 | lcov: true 149 | html: true 150 | run_cmd: ${{ vars.VERGEN_PRETTY_RUN_CMD }} 151 | secrets: inherit 152 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | Cargo.lock 3 | .ssh 4 | *.bk 5 | .DS_Store 6 | cobertura.xml 7 | lcov.info -------------------------------------------------------------------------------- /.pants-ignore: -------------------------------------------------------------------------------- 1 | { 2 | "ignore": [{ "id": "sonatype-2021-1715", "reason": "This was fixed" }] 3 | } 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "rust-analyzer.cargo.features": [ 3 | "build","cargo","color","emit_and_set","git","header","repo","rustc","serde","si","trace","unstable" 4 | ] 5 | } -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to vergen 2 | 1. Ensure you have `cargo-clippy` and `rustfmt` installed. These can be installed via rustup if you don't already have them. 3 | 1. Fork the repository 4 | 1. Run the following to clone and setup the repository. There are submodules in the testdata directory used for testing specific git scenarios 5 | 6 | ``` 7 | git clone git@github.com:/vergen.git 8 | cd vergen.git 9 | git submodule update --init 10 | ``` 11 | 12 | 1. Install `cargo-all-features` 13 | 14 | ``` 15 | cargo install cargo-all-features 16 | ``` 17 | 18 | 1. Make your changes 19 | 1. Before submitting a PR, make sure you have at least run the following 20 | 21 | ``` 22 | cargo fmt 23 | cargo clippy --all 24 | cargo build-all-features 25 | cargo test-all-features 26 | ``` 27 | 28 | 1. Push your changes to your fork and submit a PR. 29 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [workspace] 2 | resolver = "2" 3 | 4 | members = [ 5 | "test_util", 6 | "vergen", 7 | "vergen-git2", 8 | "vergen-gitcl", 9 | "vergen-gix", 10 | "vergen-lib", 11 | "vergen-pretty", 12 | ] 13 | 14 | [workspace.dependencies] 15 | anyhow = "1.0.98" 16 | bon = "3.6.3" 17 | gix = { version = "0.72.1", default-features = false, features = [ 18 | "revision", 19 | "worktree-mutation", 20 | "blocking-network-client", 21 | ] } 22 | rand = { version = "0.9.1" } 23 | regex = { version = "1.11.1" } 24 | rustversion = "1.0.20" 25 | serial_test = "3.2.0" 26 | temp-env = "0.3.6" 27 | time = { version = "0.3.41", features = [ 28 | "formatting", 29 | "local-offset", 30 | "parsing", 31 | ] } 32 | -------------------------------------------------------------------------------- /LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | https://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | https://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /LICENSE-MIT: -------------------------------------------------------------------------------- 1 | Copyright (c) 2016 The Rust Project Developers 2 | 3 | Permission is hereby granted, free of charge, to any 4 | person obtaining a copy of this software and associated 5 | documentation files (the "Software"), to deal in the 6 | Software without restriction, including without 7 | limitation the rights to use, copy, modify, merge, 8 | publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software 10 | is furnished to do so, subject to the following 11 | conditions: 12 | 13 | The above copyright notice and this permission notice 14 | shall be included in all copies or substantial portions 15 | of the Software. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF 18 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 19 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A 20 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT 21 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 23 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 24 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 25 | DEALINGS IN THE SOFTWARE. 26 | -------------------------------------------------------------------------------- /MIGRATING_v8_to_v9.md: -------------------------------------------------------------------------------- 1 | ## If you weren't using the `git` features 2 | 1. Change the `vergen` build dependency to the latest version. 3 | 4 | ```toml 5 | [dependencies] 6 | #.. 7 | [build-dependencies] 8 | # All features enabled 9 | vergen = { version = "9.0.0", features = ["build", "cargo", "rustc", "si"] } 10 | # or 11 | vergen = { version = "9.0.0", features = ["build"] } 12 | # if you wish to disable certain features 13 | ``` 14 | 15 | 2. Update `build.rs` to use the version 9 updates. 16 | ```rust 17 | use anyhow::Result; 18 | use vergen::{ 19 | BuildBuilder, CargoBuilder, Emitter, RustcBuilder, SysinfoBuilder, 20 | }; 21 | 22 | pub fn main() -> Result<()> { 23 | Emitter::default() 24 | .add_instructions(&BuildBuilder::all_build()?)? 25 | .add_instructions(&CargoBuilder::all_cargo()?)? 26 | .add_instructions(&RustcBuilder::all_rustc()?)? 27 | .add_instructions(&SysinfoBuilder::all_sysinfo()?)? 28 | .emit() 29 | } 30 | ``` 31 | 32 | ## If you were using the `gix` feature 33 | 34 | 1. Change the `vergen` build dependency to `vergen-gix` in `Cargo.toml`. Remove `git` and `gix` from your feature list. 35 | 36 | ```toml 37 | [dependencies] 38 | #.. 39 | [build-dependencies] 40 | # All features enabled 41 | vergen-gix = { version = "1.0.0", features = ["build", "cargo", "rustc", "si"] } 42 | # or 43 | vergen-gix = { version = "1.0.0", features = ["build"] } 44 | # if you wish to disable certain features 45 | ``` 46 | 47 | 2. Update `build.rs` to use the version 9 updates, replacing your `vergen` use with `vergen-gix`. 48 | 49 | ```rust 50 | use anyhow::Result; 51 | use vergen_gix::{ 52 | BuildBuilder, CargoBuilder, Emitter, GixBuilder, RustcBuilder, SysinfoBuilder, 53 | }; 54 | 55 | pub fn main() -> Result<()> { 56 | Emitter::default() 57 | .add_instructions(&BuildBuilder::all_build()?)? 58 | .add_instructions(&CargoBuilder::all_cargo()?)? 59 | .add_instructions(&GixBuilder::all_git()?)? 60 | .add_instructions(&RustcBuilder::all_rustc()?)? 61 | .add_instructions(&SysinfoBuilder::all_sysinfo()?)? 62 | .emit() 63 | } 64 | ``` 65 | ## If you were using the `gitcl` feature 66 | 67 | 1. Change the `vergen` build dependency to `vergen-gitcl` in `Cargo.toml`. Remove `git` and `gitcl` from your feature list. 68 | 69 | ```toml 70 | [dependencies] 71 | #.. 72 | [build-dependencies] 73 | # All features enabled 74 | vergen-gitcl = { version = "1.0.0", features = ["build", "cargo", "rustc", "si"] } 75 | # or 76 | vergen-gitcl = { version = "1.0.0", features = ["build"] } 77 | # if you wish to disable certain features 78 | ``` 79 | 80 | 2. Update `build.rs` to use the version 9 updates, replacing your `vergen` use with `vergen-gitcl`. 81 | 82 | ```rust 83 | use anyhow::Result; 84 | use vergen_gitcl::{ 85 | BuildBuilder, CargoBuilder, Emitter, GitclBuilder, RustcBuilder, SysinfoBuilder, 86 | }; 87 | 88 | pub fn main() -> Result<()> { 89 | Emitter::default() 90 | .add_instructions(&BuildBuilder::all_build()?)? 91 | .add_instructions(&CargoBuilder::all_cargo()?)? 92 | .add_instructions(&GitclBuilder::all_git()?)? 93 | .add_instructions(&RustcBuilder::all_rustc()?)? 94 | .add_instructions(&SysinfoBuilder::all_sysinfo()?)? 95 | .emit() 96 | } 97 | ``` 98 | ## If you were using the `git2` feature 99 | 100 | 1. Change the `vergen` build dependency to `vergen-git2` in `Cargo.toml`. Remove `git` and `git2` from your feature list. 101 | 102 | ```toml 103 | [dependencies] 104 | #.. 105 | [build-dependencies] 106 | # All features enabled 107 | vergen-git2 = { version = "1.0.0", features = ["build", "cargo", "rustc", "si"] } 108 | # or 109 | vergen-git2 = { version = "1.0.0", features = ["build"] } 110 | # if you wish to disable certain features 111 | ``` 112 | 113 | 2. Update `build.rs` to use the version 9 updates, replacing your `vergen` use with `vergen-git2`. 114 | 115 | ```rust 116 | use anyhow::Result; 117 | use vergen_git2::{ 118 | BuildBuilder, CargoBuilder, Emitter, Git2Builder, RustcBuilder, SysinfoBuilder, 119 | }; 120 | 121 | pub fn main() -> Result<()> { 122 | Emitter::default() 123 | .add_instructions(&BuildBuilder::all_build()?)? 124 | .add_instructions(&CargoBuilder::all_cargo()?)? 125 | .add_instructions(&Git2Builder::all_git()?)? 126 | .add_instructions(&RustcBuilder::all_rustc()?)? 127 | .add_instructions(&SysinfoBuilder::all_sysinfo()?)? 128 | .emit() 129 | } 130 | ``` -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vergen 2 | ### `vergen`, `vergen-git2`, `vergen-gitcl`, `vergen-gix`, `vergen-pretty` 3 | The `vergen` suite of tools allow you to embed environment variables generated at build time into your code. For example, 4 | I may care about the last git commit number and need to reference it in my code. You can configure one of the `vergen` git tools in cargo [build scripts](https://doc.rust-lang.org/cargo/reference/build-scripts.html) and can emit a `VERGEN_GIT_SHA` environment variable for use in your code. 5 | 6 | The `vergen` suite of tools can emit the following [output]((https://doc.rust-lang.org/cargo/reference/build-scripts.html#outputs-of-the-build-script)): 7 | 8 | - Will emit [`cargo:rustc-env=VAR=VALUE`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-envvarvalue) 9 | for each feature you have enabled. These can be referenced with the [`env!`](https://doc.rust-lang.org/std/macro.env.html) or [`option_env!`](https://doc.rust-lang.org/std/macro.option_env.html) macro in your code. 10 | - If using one of the git enabled libraries, will emit [`cargo:rerun-if-changed=.git/HEAD`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed). This is done to ensure any git instructions are regenerated when commits are made. 11 | - If using one of the git enabled libraries, will emit [`cargo:rerun-if-changed=.git/`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed). This is done to ensure any git instructions are regenerated when commits are made. 12 | - Can emit [`cargo:warning`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargo-warning) outputs if the 13 | [`fail_on_error`](EmitBuilder::fail_on_error) feature is not enabled and the requested variable is defaulted through error or 14 | the [`idempotent`](EmitBuilder::idempotent) flag. 15 | - Will emit [`cargo:rerun-if-changed=build.rs`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed) 16 | to rerun instruction emission if the `build.rs` file changed. 17 | - Will emit [`cargo:rerun-if-env-changed=VERGEN_IDEMPOTENT`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed) 18 | to rerun instruction emission if the `VERGEN_IDEMPOTENT` environment variable has changed. 19 | - Will emit [`cargo:rerun-if-env-changed=SOURCE_DATE_EPOCH`](https://doc.rust-lang.org/cargo/reference/build-scripts.html#rerun-if-changed) 20 | to rerun instruction emission if the `SOURCE_DATE_EPOCH` environment variable has changed. 21 | 22 | `vergen-pretty` is a macro and pretty printer for `vergen` based cargo instruction output. 23 | 24 | ## Current Releases 25 | ### vergen 26 | [![docs.rs](https://docs.rs/vergen/badge.svg)](https://docs.rs/vergen) 27 | [![Crates.io](https://img.shields.io/crates/v/vergen.svg)](https://crates.io/crates/vergen) 28 | [![Crates.io](https://img.shields.io/crates/l/vergen.svg)](https://crates.io/crates/vergen) 29 | [![Crates.io](https://img.shields.io/crates/d/vergen.svg)](https://crates.io/crates/vergen) 30 | [![codecov](https://codecov.io/gh/rustyhorde/vergen/branch/master/graph/badge.svg?token=cBXro7o2UN)](https://codecov.io/gh/rustyhorde/vergen) 31 | [![CI](https://github.com/rustyhorde/vergen/actions/workflows/vergen.yml/badge.svg)](https://github.com/rustyhorde/vergen/actions) 32 | [![sponsor](https://img.shields.io/github/sponsors/crazysacx?logo=github-sponsors)](https://github.com/sponsors/CraZySacX) 33 | 34 | ### vergen-git2 35 | [![docs.rs](https://docs.rs/vergen-git2/badge.svg)](https://docs.rs/vergen-git2) 36 | [![Crates.io](https://img.shields.io/crates/v/vergen-git2.svg)](https://crates.io/crates/vergen-git2) 37 | [![Crates.io](https://img.shields.io/crates/l/vergen-git2.svg)](https://crates.io/crates/vergen-git2) 38 | [![Crates.io](https://img.shields.io/crates/d/vergen-git2.svg)](https://crates.io/crates/vergen-git2) 39 | 40 | ### vergen-gitcl 41 | [![docs.rs](https://docs.rs/vergen-gitcl/badge.svg)](https://docs.rs/vergen-gitcl) 42 | [![Crates.io](https://img.shields.io/crates/v/vergen-gitcl.svg)](https://crates.io/crates/vergen-gitcl) 43 | [![Crates.io](https://img.shields.io/crates/l/vergen-gitcl.svg)](https://crates.io/crates/vergen-gitcl) 44 | [![Crates.io](https://img.shields.io/crates/d/vergen-gitcl.svg)](https://crates.io/crates/vergen-gitcl) 45 | 46 | ### vergen-gix 47 | [![docs.rs](https://docs.rs/vergen-gix/badge.svg)](https://docs.rs/vergen-gix) 48 | [![Crates.io](https://img.shields.io/crates/v/vergen-gix.svg)](https://crates.io/crates/vergen-gix) 49 | [![Crates.io](https://img.shields.io/crates/l/vergen-gix.svg)](https://crates.io/crates/vergen-gix) 50 | [![Crates.io](https://img.shields.io/crates/d/vergen-gix.svg)](https://crates.io/crates/vergen-gix) 51 | 52 | ### vergen-pretty 53 | [![docs.rs](https://docs.rs/vergen-pretty/badge.svg)](https://docs.rs/vergen-pretty) 54 | [![Crates.io](https://img.shields.io/crates/v/vergen-pretty.svg)](https://crates.io/crates/vergen-pretty) 55 | [![Crates.io](https://img.shields.io/crates/l/vergen-pretty.svg)](https://crates.io/crates/vergen-pretty) 56 | [![Crates.io](https://img.shields.io/crates/d/vergen-pretty.svg)](https://crates.io/crates/vergen-pretty) 57 | 58 | ## MSRV 59 | The current minimum supported rust version is 1.85.0 60 | 61 | ## ⚠️ Notes on version 9 ⚠️ 62 | * Version 9 introduces 3 new libraries, `vergen-git2`, `vergen-gitcl`, and `vergen-gix` that will be versioned independently from `vergen`. 63 | * The 3 new libraries are intended to be drop in replacements for `vergen` when you need to generate git based cargo build script instructions. 64 | * The git based features have been removed from the base `vergen` library. 65 | * `vergen` now contains the `build`, `cargo`, `rustc`, and `sysinfo` feature implementations. These features are re-exported by the new libraries allowing you to configure the output as you have previously. 66 | * Version 9 introduces the `AddCustomEntries` trait. Implementing this trait allows you to include your own custom Cargo instructions, using `vergen` as the engine to generate them. See the [`AddCustomEntries`](https://docs.rs/vergen/9.0.0/vergen/trait.AddCustomEntries.html) docs for more information. 67 | * The [version 8 branch](https://github.com/rustyhorde/vergen/tree/legacy/v8) will be maintained for some time. 68 | 69 | ### Why? 70 | This was done to resolve issues with [Cargo feature unification](https://doc.rust-lang.org/cargo/reference/features.html#mutually-exclusive-features) and mutually exclusive features. Previous versions of `vergen` had 3 mutually exclusive features (`git2`, `gitcl`, and `gix`). Feature unification could cause compilation issues if you had included a dependency that also used `vergen` but had configured a different git feature. Splitting the git backends into separate libraries helps alleviate this issue. 71 | 72 | ## Migration from version 8 73 | See the documentation at [MIGRATING_v8_to_v9.md](MIGRATING_v8_to_v9.md) 74 | 75 | ## Documentation 76 | * [vergen](https://docs.rs/vergen/latest) 77 | * [vergen-git2](https://docs.rs/vergen-git2/latest) 78 | * [vergen-gitcl](https://docs.rs/vergen-gitcl/latest) 79 | * [vergen-gix](https://docs.rs/vergen-gix/latest) 80 | * [vergen-pretty](https://docs.rs/vergen-pretty/latest) 81 | 82 | ## Contributing 83 | See the documentation at [CONTRIBUTING.md](CONTRIBUTING.md) 84 | 85 | ## License 86 | 87 | Licensed under either of 88 | * Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or https://www.apache.org/licenses/LICENSE-2.0) 89 | * MIT license ([LICENSE-MIT](LICENSE-MIT) or https://opensource.org/licenses/MIT) 90 | at your option. 91 | 92 | ### Contribution 93 | 94 | Unless you explicitly state otherwise, any contribution intentionally submitted 95 | for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any 96 | additional terms or conditions. 97 | -------------------------------------------------------------------------------- /scripts/run_all.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | cargo fmt --all -- --check; and \ 3 | scripts/run_clippy.fish; and \ 4 | scripts/run_build.fish; and \ 5 | scripts/run_test.fish; and \ 6 | scripts/run_code_cov.fish; and \ 7 | scripts/run_docs.fish 8 | 9 | -------------------------------------------------------------------------------- /scripts/run_all.ps1: -------------------------------------------------------------------------------- 1 | cargo fmt --all -- --check && scripts\run_clippy && scripts\run_build && scripts\run_test && scripts\run_code_cov && scripts\run_docs -------------------------------------------------------------------------------- /scripts/run_build.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | cargo matrix build -------------------------------------------------------------------------------- /scripts/run_build.ps1: -------------------------------------------------------------------------------- 1 | cargo matrix build -------------------------------------------------------------------------------- /scripts/run_clippy.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | cargo matrix -c nightly clippy --all-targets -- -Dwarnings 3 | -------------------------------------------------------------------------------- /scripts/run_clippy.ps1: -------------------------------------------------------------------------------- 1 | # Run the specified cargo command 2 | cargo matrix -c nightly clippy --all-targets -- -Dwarnings -------------------------------------------------------------------------------- /scripts/run_code_cov.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | cargo llvm-cov clean --workspace; and \ 3 | cargo matrix -c llvm-cov -p vergen-lib --manifest-path vergen-lib/Cargo.toml llvm-cov --no-report; and \ 4 | cargo matrix -c nightly -p vergen --manifest-path vergen/Cargo.toml llvm-cov --no-report; and \ 5 | cargo matrix -c nightly -p vergenl-git2 --manifest-path vergen-git2/Cargo.toml llvm-cov --no-report; and \ 6 | cargo matrix -c nightly -p vergen-gitcl --manifest-path vergen-gitcl/Cargo.toml llvm-cov --no-report; and \ 7 | cargo matrix -c nightly -p vergen-gix --manifest-path vergen-gix/Cargo.toml llvm-cov --no-report; and \ 8 | cargo matrix -c nightly -p vergen-pretty --manifest-path vergen-pretty/Cargo.toml llvm-cov --no-report; and \ 9 | cargo matrix -c nightly-empty -p vergen-pretty --manifest-path vergen-pretty/Cargo.toml llvm-cov --no-report; and \ 10 | cargo llvm-cov report --lcov --output-path lcov.info; and \ 11 | cargo llvm-cov report --html 12 | -------------------------------------------------------------------------------- /scripts/run_code_cov.ps1: -------------------------------------------------------------------------------- 1 | cargo llvm-cov clean --workspace && 2 | cargo matrix -c llvm-cov -p vergen-lib --manifest-path vergen-lib/Cargo.toml llvm-cov --no-report && 3 | cargo matrix -c nightly -p vergen --manifest-path vergen/Cargo.toml llvm-cov --no-report && 4 | cargo matrix -c nightly -p vergenl-git2 --manifest-path vergen-git2/Cargo.toml llvm-cov --no-report && 5 | cargo matrix -c nightly -p vergen-gitcl --manifest-path vergen-gitcl/Cargo.toml llvm-cov --no-report && 6 | cargo matrix -c nightly -p vergen-gix --manifest-path vergen-gix/Cargo.toml llvm-cov --no-report && 7 | cargo matrix -c nightly -p vergen-pretty --manifest-path vergen-pretty/Cargo.toml llvm-cov --no-report && 8 | cargo matrix -c nightly-empty -p vergen-pretty --manifest-path vergen-pretty/Cargo.toml llvm-cov --no-report && 9 | cargo llvm-cov report --lcov --output-path lcov.info && 10 | cargo llvm-cov report --html -------------------------------------------------------------------------------- /scripts/run_docs.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | echo "**** Running docs for test_util"; and \ 3 | cargo doc -p test_util -F repo; and \ 4 | echo "**** Running docs for vergen-lib"; and \ 5 | cargo doc -p vergen-lib -F build,cargo,git,rustc,si; and \ 6 | echo "**** Running docs for vergen"; and \ 7 | cargo doc -p vergen -F build,cargo,emit_and_set,rustc,si; and \ 8 | echo "**** Running docs for vergen-git2"; and \ 9 | cargo doc -p vergen-git2 -F build,cargo,emit_and_set,rustc,si; and \ 10 | echo "**** Running docs for vergen-gitcl"; and \ 11 | cargo doc -p vergen-gitcl -F build,cargo,emit_and_set,rustc,si; and \ 12 | echo "**** Running docs for vergen-gix"; and \ 13 | cargo doc -p vergen-gix -F build,cargo,emit_and_set,rustc,si; and \ 14 | echo "**** Running docs for vergen-pretty"; and \ 15 | cargo doc -p vergen-pretty -F color,header,trace -------------------------------------------------------------------------------- /scripts/run_docs.ps1: -------------------------------------------------------------------------------- 1 | cargo doc -p test_util -F repo && 2 | cargo doc -p vergen-lib -F build,cargo,git,rustc,si && 3 | cargo doc -p vergen -F build,cargo,emit_and_set,rustc,si && 4 | cargo doc -p vergen-git2 -F build,cargo,emit_and_set,rustc,si && 5 | cargo doc -p vergen-gitcl -F build,cargo,emit_and_set,rustc,si && 6 | cargo doc -p vergen-gix -F build,cargo,emit_and_set,rustc,si && 7 | cargo doc -p vergen-pretty -F color,header,trace -------------------------------------------------------------------------------- /scripts/run_test.fish: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env fish 2 | cargo matrix test -------------------------------------------------------------------------------- /scripts/run_test.ps1: -------------------------------------------------------------------------------- 1 | cargo matrix test -------------------------------------------------------------------------------- /test_util/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Jason Ozias "] 3 | categories = ["development-tools", "development-tools::build-utils"] 4 | description = "Generate 'cargo:rustc-env' instructions via 'build.rs' for use in your code via the 'env!' macro" 5 | documentation = "https://docs.rs/vergen" 6 | edition = "2024" 7 | homepage = "https://github.com/rustyhorde/vergen" 8 | keywords = ["cargo", "instructions", "build", "tool"] 9 | license = "MIT OR Apache-2.0" 10 | rust-version = "1.85.0" 11 | name = "test_util" 12 | readme = "README.md" 13 | repository = "https://github.com/rustyhorde/vergen" 14 | version = "1.0.0-beta.1" 15 | 16 | [package.metadata.cargo-matrix] 17 | [[package.metadata.cargo-matrix.channel]] 18 | name = "default" 19 | always_deny = ["unstable"] 20 | 21 | [[package.metadata.cargo-matrix.channel]] 22 | name = "nightly" 23 | always_deny = [] 24 | always_include = ["unstable"] 25 | 26 | [features] 27 | default = [] 28 | unstable = [] 29 | repo = ["gix", "rand"] 30 | 31 | [dependencies] 32 | anyhow = { workspace = true } 33 | gix = { workspace = true, optional = true} 34 | rand = { workspace = true, optional = true } 35 | temp-env = { workspace = true } 36 | 37 | [dev-dependencies] 38 | serial_test = { workspace = true } 39 | 40 | [build-dependencies] 41 | rustversion = { workspace = true } 42 | -------------------------------------------------------------------------------- /test_util/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /test_util/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /test_util/build.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | println!("cargo:rerun-if-changed=build.rs"); 3 | nightly(); 4 | beta(); 5 | stable(); 6 | } 7 | 8 | #[rustversion::nightly] 9 | fn nightly() { 10 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 11 | println!("cargo:rustc-cfg=nightly"); 12 | } 13 | 14 | #[rustversion::not(nightly)] 15 | fn nightly() { 16 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 17 | } 18 | 19 | #[rustversion::beta] 20 | fn beta() { 21 | println!("cargo:rustc-check-cfg=cfg(beta)"); 22 | println!("cargo:rustc-cfg=beta"); 23 | } 24 | 25 | #[rustversion::not(beta)] 26 | fn beta() { 27 | println!("cargo:rustc-check-cfg=cfg(beta)"); 28 | } 29 | 30 | #[rustversion::stable] 31 | fn stable() { 32 | println!("cargo:rustc-check-cfg=cfg(stable)"); 33 | println!("cargo:rustc-cfg=stable"); 34 | } 35 | 36 | #[rustversion::not(stable)] 37 | fn stable() { 38 | println!("cargo:rustc-check-cfg=cfg(stable)"); 39 | } 40 | -------------------------------------------------------------------------------- /test_util/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 vergen developers 2 | // 3 | // Licensed under the Apache License, Version 2.0 4 | // or the MIT 5 | // license , at your 6 | // option. All files in the project carrying such notice may not be copied, 7 | // modified, or distributed except according to those terms. 8 | 9 | //! `test_util` - Test utilities for the `vergen` libraries 10 | //! 11 | //! ## `vergen` - cargo feature testing utilities 12 | //! 13 | //! There are a couple of functions that are wrappers around the [`temp_env::with_vars`] 14 | //! function that serves to replicate some cargo environment variables. These are 15 | //! mainly useful for testing the cargo feature in `vergen`. 16 | //! 17 | //! # Example 18 | //! ``` 19 | //! # use anyhow::Result; 20 | //! # use std::env::var; 21 | //! # use test_util::with_cargo_vars; 22 | //! # 23 | //! let result = with_cargo_vars(|| { 24 | //! assert_eq!(var("OPT_LEVEL")?, "1"); 25 | //! Ok(()) 26 | //! }); 27 | //! assert!(result.is_ok()); 28 | //! ``` 29 | //! 30 | //! ``` 31 | //! # use anyhow::Result; 32 | //! # use std::env::var; 33 | //! # use test_util::with_cargo_vars_ext; 34 | //! # 35 | //! let result = with_cargo_vars_ext(&[("MY_VAR", Some("12"))], || { 36 | //! assert_eq!(var("MY_VAR")?, "12"); 37 | //! assert_eq!(var("OPT_LEVEL")?, "1"); 38 | //! Ok(()) 39 | //! }); 40 | //! assert!(result.is_ok()); 41 | //! ``` 42 | //! 43 | #![cfg_attr( 44 | feature = "repo", 45 | doc = r"## `vergen` - Test git repositories (`repo` feature) 46 | 47 | If you enable the `repo` feature of `test_util` you can also use 48 | the [`TestRepos`] struct to creat temporary git repositories useful for `vergen-gi*` testing 49 | 50 | # Example 51 | ``` 52 | # use anyhow::Result; 53 | # use std::path::PathBuf; 54 | # use test_util::TestRepos; 55 | # pub fn main() -> Result<()> { 56 | let mut path = PathBuf::default(); 57 | { 58 | let repo = TestRepos::new(false, false, false)?; 59 | path = repo.path(); 60 | assert!(gix::discover(&path).is_ok()); 61 | assert!(path.exists()); 62 | } 63 | // When dropped, the repositories will be removed. 64 | assert!(!path.exists()); 65 | # Ok(()) 66 | # } 67 | ``` 68 | " 69 | )] 70 | // rustc lints 71 | #![cfg_attr( 72 | all(feature = "unstable", nightly), 73 | feature( 74 | multiple_supertrait_upcastable, 75 | must_not_suspend, 76 | non_exhaustive_omitted_patterns_lint, 77 | rustdoc_missing_doc_code_examples, 78 | strict_provenance_lints, 79 | supertrait_item_shadowing, 80 | unqualified_local_imports, 81 | ) 82 | )] 83 | #![cfg_attr(nightly, allow(single_use_lifetimes))] 84 | #![cfg_attr( 85 | nightly, 86 | deny( 87 | absolute_paths_not_starting_with_crate, 88 | ambiguous_glob_imports, 89 | ambiguous_glob_reexports, 90 | ambiguous_negative_literals, 91 | ambiguous_wide_pointer_comparisons, 92 | anonymous_parameters, 93 | array_into_iter, 94 | asm_sub_register, 95 | async_fn_in_trait, 96 | bad_asm_style, 97 | bare_trait_objects, 98 | boxed_slice_into_iter, 99 | break_with_label_and_loop, 100 | clashing_extern_declarations, 101 | closure_returning_async_block, 102 | coherence_leak_check, 103 | confusable_idents, 104 | const_evaluatable_unchecked, 105 | const_item_mutation, 106 | dangling_pointers_from_temporaries, 107 | dead_code, 108 | dependency_on_unit_never_type_fallback, 109 | deprecated, 110 | deprecated_in_future, 111 | deprecated_safe_2024, 112 | deprecated_where_clause_location, 113 | deref_into_dyn_supertrait, 114 | deref_nullptr, 115 | double_negations, 116 | drop_bounds, 117 | dropping_copy_types, 118 | dropping_references, 119 | duplicate_macro_attributes, 120 | dyn_drop, 121 | edition_2024_expr_fragment_specifier, 122 | elided_lifetimes_in_paths, 123 | elided_named_lifetimes, 124 | ellipsis_inclusive_range_patterns, 125 | explicit_outlives_requirements, 126 | exported_private_dependencies, 127 | ffi_unwind_calls, 128 | forbidden_lint_groups, 129 | forgetting_copy_types, 130 | forgetting_references, 131 | for_loops_over_fallibles, 132 | function_item_references, 133 | hidden_glob_reexports, 134 | if_let_rescope, 135 | impl_trait_overcaptures, 136 | impl_trait_redundant_captures, 137 | improper_ctypes, 138 | improper_ctypes_definitions, 139 | inline_no_sanitize, 140 | internal_features, 141 | invalid_from_utf8, 142 | invalid_macro_export_arguments, 143 | invalid_nan_comparisons, 144 | invalid_value, 145 | irrefutable_let_patterns, 146 | keyword_idents_2018, 147 | keyword_idents_2024, 148 | large_assignments, 149 | late_bound_lifetime_arguments, 150 | legacy_derive_helpers, 151 | let_underscore_drop, 152 | macro_use_extern_crate, 153 | map_unit_fn, 154 | meta_variable_misuse, 155 | missing_abi, 156 | missing_copy_implementations, 157 | missing_debug_implementations, 158 | missing_docs, 159 | missing_unsafe_on_extern, 160 | mixed_script_confusables, 161 | named_arguments_used_positionally, 162 | never_type_fallback_flowing_into_unsafe, 163 | no_mangle_generic_items, 164 | non_ascii_idents, 165 | non_camel_case_types, 166 | non_contiguous_range_endpoints, 167 | non_fmt_panics, 168 | non_local_definitions, 169 | non_shorthand_field_patterns, 170 | non_snake_case, 171 | non_upper_case_globals, 172 | noop_method_call, 173 | opaque_hidden_inferred_bound, 174 | out_of_scope_macro_calls, 175 | overlapping_range_endpoints, 176 | path_statements, 177 | private_bounds, 178 | private_interfaces, 179 | ptr_to_integer_transmute_in_consts, 180 | redundant_imports, 181 | redundant_lifetimes, 182 | redundant_semicolons, 183 | refining_impl_trait_internal, 184 | refining_impl_trait_reachable, 185 | renamed_and_removed_lints, 186 | repr_transparent_external_private_fields, 187 | rust_2021_incompatible_closure_captures, 188 | rust_2021_incompatible_or_patterns, 189 | rust_2021_prefixes_incompatible_syntax, 190 | rust_2021_prelude_collisions, 191 | rust_2024_guarded_string_incompatible_syntax, 192 | rust_2024_incompatible_pat, 193 | rust_2024_prelude_collisions, 194 | self_constructor_from_outer_item, 195 | semicolon_in_expressions_from_macros, 196 | single_use_lifetimes, 197 | special_module_name, 198 | stable_features, 199 | static_mut_refs, 200 | suspicious_double_ref_op, 201 | tail_expr_drop_order, 202 | trivial_bounds, 203 | trivial_casts, 204 | trivial_numeric_casts, 205 | type_alias_bounds, 206 | tyvar_behind_raw_pointer, 207 | uncommon_codepoints, 208 | unconditional_recursion, 209 | uncovered_param_in_projection, 210 | unexpected_cfgs, 211 | unfulfilled_lint_expectations, 212 | ungated_async_fn_track_caller, 213 | uninhabited_static, 214 | unit_bindings, 215 | unknown_lints, 216 | unknown_or_malformed_diagnostic_attributes, 217 | unnameable_test_items, 218 | unnameable_types, 219 | unpredictable_function_pointer_comparisons, 220 | unreachable_code, 221 | unreachable_patterns, 222 | unreachable_pub, 223 | unsafe_attr_outside_unsafe, 224 | unsafe_code, 225 | unsafe_op_in_unsafe_fn, 226 | unstable_name_collisions, 227 | unstable_syntax_pre_expansion, 228 | unsupported_fn_ptr_calling_conventions, 229 | unused_allocation, 230 | unused_assignments, 231 | unused_associated_type_bounds, 232 | unused_attributes, 233 | unused_braces, 234 | unused_comparisons, 235 | unused_crate_dependencies, 236 | unused_doc_comments, 237 | unused_extern_crates, 238 | unused_features, 239 | unused_import_braces, 240 | unused_imports, 241 | unused_labels, 242 | unused_lifetimes, 243 | unused_macro_rules, 244 | unused_macros, 245 | unused_must_use, 246 | unused_mut, 247 | unused_parens, 248 | unused_qualifications, 249 | unused_results, 250 | unused_unsafe, 251 | unused_variables, 252 | useless_ptr_null_checks, 253 | uses_power_alignment, 254 | variant_size_differences, 255 | wasm_c_abi, 256 | while_true, 257 | ) 258 | )] 259 | // If nightly and unstable, allow `incomplete_features` and `unstable_features` 260 | #![cfg_attr( 261 | all(feature = "unstable", nightly), 262 | allow(incomplete_features, unstable_features) 263 | )] 264 | // If nightly and not unstable, deny `incomplete_features` and `unstable_features` 265 | #![cfg_attr( 266 | all(not(feature = "unstable"), nightly), 267 | deny(incomplete_features, unstable_features) 268 | )] 269 | // The unstable lints 270 | #![cfg_attr( 271 | all(feature = "unstable", nightly), 272 | deny( 273 | fuzzy_provenance_casts, 274 | lossy_provenance_casts, 275 | multiple_supertrait_upcastable, 276 | must_not_suspend, 277 | non_exhaustive_omitted_patterns, 278 | supertrait_item_shadowing_definition, 279 | supertrait_item_shadowing_usage, 280 | unqualified_local_imports, 281 | ) 282 | )] 283 | // clippy lints 284 | #![cfg_attr(nightly, deny(clippy::all, clippy::pedantic))] 285 | // rustdoc lints 286 | #![cfg_attr( 287 | nightly, 288 | deny( 289 | rustdoc::bare_urls, 290 | rustdoc::broken_intra_doc_links, 291 | rustdoc::invalid_codeblock_attributes, 292 | rustdoc::invalid_html_tags, 293 | rustdoc::missing_crate_level_docs, 294 | rustdoc::private_doc_tests, 295 | rustdoc::private_intra_doc_links, 296 | ) 297 | )] 298 | #![cfg_attr( 299 | all(nightly, feature = "unstable"), 300 | deny(rustdoc::missing_doc_code_examples) 301 | )] 302 | #![cfg_attr(all(doc, nightly), feature(doc_auto_cfg))] 303 | #![cfg_attr(all(docsrs, nightly), feature(doc_cfg))] 304 | 305 | #[cfg(all(test, not(feature = "repo")))] 306 | use {anyhow as _, serial_test as _}; 307 | 308 | #[cfg(feature = "repo")] 309 | mod repo; 310 | mod utils; 311 | 312 | #[cfg(feature = "repo")] 313 | pub use self::repo::TEST_MTIME; 314 | #[cfg(feature = "repo")] 315 | pub use self::repo::TestRepos; 316 | pub use self::utils::with_cargo_vars; 317 | pub use self::utils::with_cargo_vars_ext; 318 | -------------------------------------------------------------------------------- /test_util/src/repo/mod.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use git::{ 3 | Id, ObjectId, 4 | clone::PrepareFetch, 5 | config::CommitAutoRollback, 6 | create::{Kind, Options}, 7 | interrupt::IS_INTERRUPTED, 8 | objs::{ 9 | Tree, 10 | tree::{Entry, EntryKind}, 11 | }, 12 | open, 13 | path::os_str_into_bstr, 14 | progress::Discard, 15 | refs::transaction::PreviousValue, 16 | remote::fetch::Shallow, 17 | url::parse, 18 | }; 19 | use gix as git; 20 | use rand::{Rng, distr::Alphanumeric, rng}; 21 | use std::{ 22 | env, 23 | fs::{self, FileTimes, OpenOptions}, 24 | io::{BufWriter, Write}, 25 | path::PathBuf, 26 | sync::LazyLock, 27 | time::{Duration, SystemTime, UNIX_EPOCH}, 28 | }; 29 | use std::{fs::File, num::NonZeroU32}; 30 | 31 | const BARE_REPO_PREFIX: &str = "vergen_tmp"; 32 | const BARE_REPO_SUFFIX: &str = ".git"; 33 | const CLONE_NAME_PREFIX: &str = "vergen_tmp"; 34 | const RUNNER_TEMP_ENV: &str = "RUNNER_TEMP"; 35 | const MAGIC_MTIME: u64 = 1_234_567_890; 36 | 37 | /// mtime to use for testing 38 | pub static TEST_MTIME: LazyLock = 39 | LazyLock::new(|| UNIX_EPOCH + Duration::from_secs(MAGIC_MTIME)); 40 | 41 | /// Utility to create a temporary bare repository and a repository cloned from the 42 | /// bare repository. 43 | /// 44 | /// # Example 45 | /// ``` 46 | /// # use anyhow::Result; 47 | /// # use std::path::PathBuf; 48 | /// # use test_util::TestRepos; 49 | /// # pub fn main() -> Result<()> { 50 | /// let mut path = PathBuf::default(); 51 | /// { 52 | /// let repo = TestRepos::new(false, false, false)?; 53 | /// path = repo.path(); 54 | /// assert!(gix::discover(&path).is_ok()); 55 | /// assert!(path.exists()); 56 | /// } 57 | /// // When dropped, the repositories will be removed. 58 | /// assert!(!path.exists()); 59 | /// # Ok(()) 60 | /// # } 61 | /// ``` 62 | #[derive(Clone, Debug)] 63 | pub struct TestRepos { 64 | bare_repo_path: PathBuf, 65 | clone_path: PathBuf, 66 | } 67 | 68 | impl TestRepos { 69 | /// Create a new bare repository and a repository cloned from the bare repository. 70 | /// 71 | /// Optionally, modify a tracked file 72 | /// Optionally, include an untracked file 73 | /// Optionally, create a shallow clone 74 | /// 75 | /// # Example 76 | /// ``` 77 | /// # use anyhow::Result; 78 | /// # use std::path::PathBuf; 79 | /// # use test_util::TestRepos; 80 | /// # pub fn main() -> Result<()> { 81 | /// let mut path = PathBuf::default(); 82 | /// { 83 | /// let repo = TestRepos::new(false, false, false)?; 84 | /// path = repo.path(); 85 | /// assert!(gix::discover(&path).is_ok()); 86 | /// assert!(path.exists()); 87 | /// } 88 | /// // When dropped, the repositories will be removed. 89 | /// assert!(!path.exists()); 90 | /// # Ok(()) 91 | /// # } 92 | /// ``` 93 | /// 94 | /// # Errors 95 | /// Many errors can occur mostly from the `gix` library 96 | pub fn new(modify_tracked: bool, include_untracked: bool, shallow_clone: bool) -> Result { 97 | let bare_repo_path = Self::repo_path(); 98 | let clone_path = Self::clone_path(); 99 | 100 | let mut test_repo = TestRepos { 101 | bare_repo_path, 102 | clone_path, 103 | }; 104 | 105 | test_repo.create_repository()?; 106 | test_repo.clone_from_bare_repo(shallow_clone)?; 107 | 108 | if modify_tracked { 109 | test_repo.modify_tracked()?; 110 | } 111 | 112 | if include_untracked { 113 | test_repo.create_untracked_file()?; 114 | } 115 | 116 | Ok(test_repo) 117 | } 118 | 119 | fn create_repository(&mut self) -> Result<()> { 120 | let path = &self.bare_repo_path; 121 | 122 | // Always make sure to re-create repo in CI 123 | if let Ok(_ci) = env::var("CI") { 124 | let _res = fs::remove_dir_all(path); 125 | } 126 | 127 | // Initialize a bare repository 128 | let mut repo = git::init_bare(path)?; 129 | 130 | // Create an empty tree for the initial commit 131 | let mut tree = Tree::empty(); 132 | let empty_tree_id = repo.write_object(&tree)?.detach(); 133 | 134 | // Setup the base configuration 135 | let mut config = repo.config_snapshot_mut(); 136 | let _old = config.set_raw_value(&"user.name", "Vergen Test")?; 137 | let _old = config.set_raw_value(&"user.email", "vergen@blah.com")?; 138 | 139 | { 140 | // Create an empty commit with the initial empty tree 141 | let committer = config.commit_auto_rollback()?; 142 | 143 | // Make an initial empty commit 144 | let initial_commit_id = committer.commit( 145 | "HEAD", 146 | "initial commit", 147 | empty_tree_id, 148 | git::commit::NO_PARENT_IDS, 149 | )?; 150 | 151 | // Create a commit 152 | let first_commit_id = Self::create_commit( 153 | &mut tree, 154 | &committer, 155 | b"hello, world", 156 | "foo.txt", 157 | "foo commit", 158 | initial_commit_id.into(), 159 | )?; 160 | 161 | // Create an annotated tag against the first commit 162 | let _tag_id = committer.tag( 163 | "0.1.0", 164 | first_commit_id, 165 | git::objs::Kind::Commit, 166 | None, 167 | "v0.1.0", 168 | PreviousValue::MustNotExist, 169 | )?; 170 | 171 | // Create a second commit 172 | let mut second_tree = Tree::empty(); 173 | let second_commit_id = Self::create_commit( 174 | &mut second_tree, 175 | &committer, 176 | b"Hello, World!", 177 | "foo.txt", 178 | "such bad casing", 179 | first_commit_id.into(), 180 | )?; 181 | 182 | // Create a lightweight tag against the second commit 183 | let _tag_id = committer.tag_reference( 184 | "0.2.0-rc1", 185 | second_commit_id, 186 | PreviousValue::MustNotExist, 187 | )?; 188 | 189 | // Create a third commit 190 | let mut third_tree = Tree::empty(); 191 | let _third_commit_id = Self::create_commit( 192 | &mut third_tree, 193 | &committer, 194 | b"this is my third commit", 195 | "foo.txt", 196 | "third commit", 197 | second_commit_id.into(), 198 | )?; 199 | } 200 | 201 | Ok(()) 202 | } 203 | 204 | fn clone_from_bare_repo(&mut self, shallow_clone: bool) -> Result<()> { 205 | let bare_repo_path = &self.bare_repo_path; 206 | let clone_path = &self.clone_path; 207 | 208 | // Always make sure to clone a fresh directory in CI 209 | if let Ok(_ci) = env::var("CI") { 210 | let _res = fs::remove_dir_all(clone_path); 211 | } 212 | 213 | // Setup the directory 214 | fs::create_dir_all(clone_path)?; 215 | 216 | // Clone into the directory 217 | let url = parse(os_str_into_bstr(bare_repo_path.as_os_str())?)?; 218 | let opts = open::Options::isolated() 219 | .config_overrides(["user.name=Vergen Test", "user.email=vergen@blah.com"]); 220 | let mut prep = PrepareFetch::new( 221 | url, 222 | clone_path, 223 | Kind::WithWorktree, 224 | Options::default(), 225 | opts, 226 | )?; 227 | if shallow_clone { 228 | if let Some(one) = NonZeroU32::new(1) { 229 | prep = prep.with_shallow(Shallow::DepthAtRemote(one)); 230 | } 231 | } 232 | let (mut prepare_checkout, _) = prep.fetch_then_checkout(Discard, &IS_INTERRUPTED)?; 233 | let (_repo, _) = prepare_checkout.main_worktree(Discard, &IS_INTERRUPTED)?; 234 | 235 | Ok(()) 236 | } 237 | 238 | fn create_commit<'a>( 239 | tree: &mut Tree, 240 | committer: &'a CommitAutoRollback<'_>, 241 | blob: &[u8], 242 | filename: &str, 243 | message: &str, 244 | parent: ObjectId, 245 | ) -> Result> { 246 | // Create a BLOB to commit, along with the corresponding tree entry 247 | let blob_id = committer.write_blob(blob)?.into(); 248 | let entry = Entry { 249 | mode: EntryKind::Blob.into(), 250 | filename: filename.into(), 251 | oid: blob_id, 252 | }; 253 | 254 | // Add everything to the tree 255 | tree.entries.push(entry); 256 | let tree_id = committer.write_object(&*tree)?; 257 | 258 | // Make the commit 259 | let commit_id = committer.commit("HEAD", message, tree_id, [parent])?; 260 | 261 | Ok(commit_id) 262 | } 263 | 264 | fn modify_tracked(&mut self) -> Result<()> { 265 | // "edit" a file to create a diffence between the index and worktree (i.e. dirty) 266 | let file_path = self.clone_path.join("foo.txt"); 267 | let file = OpenOptions::new().append(true).open(file_path)?; 268 | let mut writer = BufWriter::new(file); 269 | writeln!(writer, "another test line")?; 270 | 271 | Ok(()) 272 | } 273 | 274 | /// Get the path of the cloned repository 275 | /// 276 | /// # Example 277 | /// ``` 278 | /// # use anyhow::Result; 279 | /// # use test_util::TestRepos; 280 | /// # 281 | /// # pub fn main() -> Result<()> { 282 | /// let repo = TestRepos::new(false, false, false)?; 283 | /// assert!(repo.path().exists()); 284 | /// # Ok(()) 285 | /// # } 286 | /// ``` 287 | #[must_use] 288 | pub fn path(&self) -> PathBuf { 289 | self.clone_path.clone() 290 | } 291 | 292 | // Create a new file that is not under git control 293 | fn create_untracked_file(&mut self) -> Result<()> { 294 | let file_path = self.clone_path.join("bar.txt"); 295 | let bar = File::create(file_path)?; 296 | let mut writer = BufWriter::new(bar); 297 | writeln!(writer, "an uncontrolled test line")?; 298 | 299 | Ok(()) 300 | } 301 | 302 | fn temp_path() -> PathBuf { 303 | if let Ok(temp_path) = env::var(RUNNER_TEMP_ENV) { 304 | PathBuf::from(temp_path) 305 | } else { 306 | env::temp_dir() 307 | } 308 | } 309 | 310 | fn rand_five() -> String { 311 | rng() 312 | .sample_iter(&Alphanumeric) 313 | .take(5) 314 | .map(char::from) 315 | .collect() 316 | } 317 | 318 | fn repo_path() -> PathBuf { 319 | let temp_path = Self::temp_path(); 320 | let rand_repo_path = format!("{BARE_REPO_PREFIX}_{}{BARE_REPO_SUFFIX}", Self::rand_five()); 321 | temp_path.join(rand_repo_path) 322 | } 323 | 324 | fn clone_path() -> PathBuf { 325 | let temp_path = Self::temp_path(); 326 | let rand_clone_path = format!("{CLONE_NAME_PREFIX}_{}", Self::rand_five()); 327 | temp_path.join(rand_clone_path) 328 | } 329 | 330 | /// Set mtime on .git index file 331 | /// 332 | /// # Errors 333 | /// * File open and modifiy errors 334 | /// 335 | pub fn set_index_magic_mtime(&self) -> Result<()> { 336 | let index_path = self.path().join(".git").join("index"); 337 | File::open(&index_path)?.set_times(FileTimes::new().set_modified(*TEST_MTIME))?; 338 | Ok(()) 339 | } 340 | 341 | /// Get mtime on the .git index file 342 | /// 343 | /// # Errors 344 | /// * File open and modifiy errors 345 | /// 346 | pub fn get_index_magic_mtime(&self) -> Result { 347 | let index_path = self.path().join(".git").join("index"); 348 | Ok(File::open(&index_path)?.metadata()?.modified()?) 349 | } 350 | } 351 | 352 | impl Drop for TestRepos { 353 | fn drop(&mut self) { 354 | let _res = fs::remove_dir_all(&self.clone_path); 355 | let _res = fs::remove_dir_all(&self.bare_repo_path); 356 | } 357 | } 358 | 359 | #[cfg(test)] 360 | mod test { 361 | use super::{RUNNER_TEMP_ENV, TestRepos}; 362 | use anyhow::Result; 363 | use serial_test::serial; 364 | 365 | #[test] 366 | #[serial] 367 | fn temp_dir_works() -> Result<()> { 368 | temp_env::with_var(RUNNER_TEMP_ENV, None::, || { 369 | let repo = || -> Result { 370 | let repo = TestRepos::new(false, false, false)?; 371 | Ok(repo) 372 | }(); 373 | assert!(repo.is_ok()); 374 | }); 375 | Ok(()) 376 | } 377 | } 378 | -------------------------------------------------------------------------------- /test_util/src/utils.rs: -------------------------------------------------------------------------------- 1 | use std::sync::LazyLock; 2 | 3 | use anyhow::Result; 4 | use temp_env::with_vars; 5 | 6 | static DEFAULT_KVS: LazyLock)>> = LazyLock::new(|| { 7 | vec![ 8 | ("CARGO_FEATURE_BUILD", Some("build")), 9 | ("CARGO_FEATURE_GIT", Some("git")), 10 | ("DEBUG", Some("true")), 11 | ("OPT_LEVEL", Some("1")), 12 | ("TARGET", Some("x86_64-unknown-linux-gnu")), 13 | ] 14 | }); 15 | 16 | /// Wrap a closure with cargo environment variables to use within a test 17 | /// 18 | /// * `CARGO_FEATURE_BUILD=build` 19 | /// * `CARGO_FEATURE_GIT=git` 20 | /// * `DEBUG=true` 21 | /// * `OPT_LEVEL=1` 22 | /// * `TARGET=x86_64-unknown-linux-gnu` 23 | /// 24 | /// Uses [`temp_env::with_vars`] internally to provide a safe environment to do this with tests. 25 | /// 26 | /// # Example 27 | /// ``` 28 | /// # use anyhow::Result; 29 | /// # use std::env::var; 30 | /// # use test_util::with_cargo_vars; 31 | /// # 32 | /// let result = with_cargo_vars(|| { 33 | /// assert_eq!(var("OPT_LEVEL")?, "1"); 34 | /// Ok(()) 35 | /// }); 36 | /// assert!(result.is_ok()); 37 | /// ``` 38 | /// 39 | /// # Errors 40 | /// 41 | /// Errors may be generate by the closure 42 | /// 43 | pub fn with_cargo_vars(closure: F) -> Result 44 | where 45 | F: FnOnce() -> Result, 46 | { 47 | with_cargo_vars_ext(&[], closure) 48 | } 49 | 50 | /// Wrap a closure with cargo environment variables to use within a test 51 | /// plus any other environment variables you may need. 52 | /// 53 | /// * `CARGO_FEATURE_BUILD=build` 54 | /// * `CARGO_FEATURE_GIT=git` 55 | /// * `DEBUG=true` 56 | /// * `OPT_LEVEL=1` 57 | /// * `TARGET=x86_64-unknown-linux-gnu` 58 | /// * `MY_FUNKY_ENV=this` 59 | /// 60 | /// Uses [`temp_env::with_vars`] internally to provide a safe environment to do this with tests. 61 | /// 62 | /// # Example 63 | /// ``` 64 | /// # use anyhow::Result; 65 | /// # use std::env::var; 66 | /// # use test_util::with_cargo_vars_ext; 67 | /// # 68 | /// let result = with_cargo_vars_ext(&[("MY_VAR", Some("12"))], || { 69 | /// assert_eq!(var("MY_VAR")?, "12"); 70 | /// assert_eq!(var("OPT_LEVEL")?, "1"); 71 | /// Ok(()) 72 | /// }); 73 | /// assert!(result.is_ok()); 74 | /// ``` 75 | /// 76 | /// # Errors 77 | /// 78 | /// Errors may be generate by the closure 79 | /// 80 | pub fn with_cargo_vars_ext(kvs: &[(&str, Option<&str>)], closure: F) -> Result 81 | where 82 | F: FnOnce() -> Result, 83 | { 84 | let mut in_kvs: Vec<(&str, Option<&str>)> = kvs.as_ref().to_vec(); 85 | in_kvs.extend_from_slice(&DEFAULT_KVS); 86 | with_vars(in_kvs, closure) 87 | } 88 | -------------------------------------------------------------------------------- /vergen-git2/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Jason Ozias "] 3 | categories = ["development-tools", "development-tools::build-utils"] 4 | description = "Generate 'cargo:rustc-env' instructions via 'build.rs' for use in your code via the 'env!' macro" 5 | documentation = "https://docs.rs/vergen" 6 | edition = "2024" 7 | homepage = "https://github.com/rustyhorde/vergen" 8 | keywords = ["cargo", "instructions", "build", "tool"] 9 | license = "MIT OR Apache-2.0" 10 | rust-version = "1.85.0" 11 | name = "vergen-git2" 12 | readme = "README.md" 13 | repository = "https://github.com/rustyhorde/vergen" 14 | version = "2.0.0-beta.1" 15 | 16 | [package.metadata.cargo-matrix] 17 | [[package.metadata.cargo-matrix.channel]] 18 | name = "default" 19 | always_deny = ["emit_and_set", "unstable"] 20 | 21 | [[package.metadata.cargo-matrix.channel]] 22 | name = "nightly" 23 | always_deny = ["emit_and_set"] 24 | always_include = ["unstable"] 25 | 26 | [features] 27 | default = [] 28 | build = ["vergen/build"] 29 | cargo = ["vergen/cargo"] 30 | cargo_metadata = ["vergen/cargo_metadata"] 31 | emit_and_set = ["vergen-lib/emit_and_set"] 32 | rustc = ["vergen/rustc"] 33 | unstable = ["vergen/unstable", "vergen-lib/unstable"] 34 | si = ["vergen/si"] 35 | 36 | [dependencies] 37 | anyhow = { workspace = true } 38 | bon = { workspace = true } 39 | git2-rs = { version = "0.20.2", package = "git2", default-features = false } 40 | time = { workspace = true } 41 | vergen = { version = "10.0.0-beta.1", path = "../vergen", default-features = false } 42 | vergen-lib = { version = "1.0.0-beta.1", path = "../vergen-lib", features = ["git"] } 43 | 44 | [build-dependencies] 45 | rustversion = { workspace = true } 46 | 47 | [dev-dependencies] 48 | regex = { workspace = true } 49 | serial_test = { workspace = true } 50 | temp-env = { workspace = true } 51 | test_util = { path = "../test_util", features = ["repo", "unstable"] } 52 | 53 | [package.metadata.docs.rs] 54 | features = ["build", "cargo", "emit_and_set", "rustc", "si"] 55 | rustdoc-args = ["--cfg", "docsrs"] 56 | -------------------------------------------------------------------------------- /vergen-git2/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /vergen-git2/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /vergen-git2/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /vergen-git2/build.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | println!("cargo:rerun-if-changed=build.rs"); 3 | nightly(); 4 | beta(); 5 | stable(); 6 | } 7 | 8 | #[rustversion::nightly] 9 | fn nightly() { 10 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 11 | println!("cargo:rustc-cfg=nightly"); 12 | } 13 | 14 | #[rustversion::not(nightly)] 15 | fn nightly() { 16 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 17 | } 18 | 19 | #[rustversion::beta] 20 | fn beta() { 21 | println!("cargo:rustc-check-cfg=cfg(beta)"); 22 | println!("cargo:rustc-cfg=beta"); 23 | } 24 | 25 | #[rustversion::not(beta)] 26 | fn beta() { 27 | println!("cargo:rustc-check-cfg=cfg(beta)"); 28 | } 29 | 30 | #[rustversion::stable] 31 | fn stable() { 32 | println!("cargo:rustc-check-cfg=cfg(stable)"); 33 | println!("cargo:rustc-cfg=stable"); 34 | } 35 | 36 | #[rustversion::not(stable)] 37 | fn stable() { 38 | println!("cargo:rustc-check-cfg=cfg(stable)"); 39 | } 40 | -------------------------------------------------------------------------------- /vergen-gitcl/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Jason Ozias "] 3 | categories = ["development-tools", "development-tools::build-utils"] 4 | description = "Generate 'cargo:rustc-env' instructions via 'build.rs' for use in your code via the 'env!' macro" 5 | documentation = "https://docs.rs/vergen" 6 | edition = "2024" 7 | homepage = "https://github.com/rustyhorde/vergen" 8 | keywords = ["cargo", "instructions", "build", "tool"] 9 | license = "MIT OR Apache-2.0" 10 | rust-version = "1.85.0" 11 | name = "vergen-gitcl" 12 | readme = "README.md" 13 | repository = "https://github.com/rustyhorde/vergen" 14 | version = "2.0.0-beta.1" 15 | 16 | [package.metadata.cargo-matrix] 17 | [[package.metadata.cargo-matrix.channel]] 18 | name = "default" 19 | always_deny = ["emit_and_set", "unstable"] 20 | 21 | [[package.metadata.cargo-matrix.channel]] 22 | name = "nightly" 23 | always_deny = ["emit_and_set"] 24 | always_include = ["unstable"] 25 | 26 | [features] 27 | default = [] 28 | build = ["vergen/build"] 29 | cargo = ["vergen/cargo"] 30 | cargo_metadata = ["vergen/cargo_metadata"] 31 | emit_and_set = ["vergen-lib/emit_and_set"] 32 | rustc = ["vergen/rustc"] 33 | unstable = ["vergen/unstable", "vergen-lib/unstable"] 34 | si = ["vergen/si"] 35 | 36 | [dependencies] 37 | anyhow = { workspace = true } 38 | bon = { workspace = true } 39 | time = { workspace = true } 40 | vergen = { version = "10.0.0-beta.1", path = "../vergen", default-features = false } 41 | vergen-lib = { version = "1.0.0-beta.1", path = "../vergen-lib", features = ["git"] } 42 | 43 | [build-dependencies] 44 | rustversion = { workspace = true } 45 | 46 | [dev-dependencies] 47 | regex = { workspace = true } 48 | serial_test = { workspace = true } 49 | temp-env = { workspace = true } 50 | test_util = { path = "../test_util", features = ["repo", "unstable"] } 51 | 52 | [package.metadata.docs.rs] 53 | features = ["build", "cargo", "emit_and_set", "rustc", "si"] 54 | rustdoc-args = ["--cfg", "docsrs"] 55 | -------------------------------------------------------------------------------- /vergen-gitcl/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /vergen-gitcl/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /vergen-gitcl/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /vergen-gitcl/build.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | println!("cargo:rerun-if-changed=build.rs"); 3 | nightly(); 4 | beta(); 5 | stable(); 6 | } 7 | 8 | #[rustversion::nightly] 9 | fn nightly() { 10 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 11 | println!("cargo:rustc-cfg=nightly"); 12 | } 13 | 14 | #[rustversion::not(nightly)] 15 | fn nightly() { 16 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 17 | } 18 | 19 | #[rustversion::beta] 20 | fn beta() { 21 | println!("cargo:rustc-check-cfg=cfg(beta)"); 22 | println!("cargo:rustc-cfg=beta"); 23 | } 24 | 25 | #[rustversion::not(beta)] 26 | fn beta() { 27 | println!("cargo:rustc-check-cfg=cfg(beta)"); 28 | } 29 | 30 | #[rustversion::stable] 31 | fn stable() { 32 | println!("cargo:rustc-check-cfg=cfg(stable)"); 33 | println!("cargo:rustc-cfg=stable"); 34 | } 35 | 36 | #[rustversion::not(stable)] 37 | fn stable() { 38 | println!("cargo:rustc-check-cfg=cfg(stable)"); 39 | } 40 | -------------------------------------------------------------------------------- /vergen-gix/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Jason Ozias "] 3 | categories = ["development-tools", "development-tools::build-utils"] 4 | description = "Generate 'cargo:rustc-env' instructions via 'build.rs' for use in your code via the 'env!' macro" 5 | documentation = "https://docs.rs/vergen" 6 | edition = "2024" 7 | homepage = "https://github.com/rustyhorde/vergen" 8 | keywords = ["cargo", "instructions", "build", "tool"] 9 | license = "MIT OR Apache-2.0" 10 | rust-version = "1.85.0" 11 | name = "vergen-gix" 12 | readme = "README.md" 13 | repository = "https://github.com/rustyhorde/vergen" 14 | version = "2.0.0-beta.1" 15 | 16 | [package.metadata.cargo-matrix] 17 | [[package.metadata.cargo-matrix.channel]] 18 | name = "default" 19 | always_deny = ["emit_and_set", "unstable"] 20 | 21 | [[package.metadata.cargo-matrix.channel]] 22 | name = "nightly" 23 | always_deny = ["emit_and_set"] 24 | always_include = ["unstable"] 25 | 26 | [[package.metadata.cargo-matrix.channel]] 27 | name = "llvm-cov" 28 | always_deny = ["emit_and_set"] 29 | always_include = ["unstable"] 30 | 31 | [features] 32 | default = [] 33 | build = ["vergen/build"] 34 | cargo = ["vergen/cargo"] 35 | cargo_metadata = ["vergen/cargo_metadata"] 36 | emit_and_set = ["vergen-lib/emit_and_set"] 37 | rustc = ["vergen/rustc"] 38 | unstable = ["vergen/unstable", "vergen-lib/unstable"] 39 | si = ["vergen/si"] 40 | 41 | [dependencies] 42 | anyhow = { workspace = true } 43 | bon = { workspace = true } 44 | gix = { workspace = true, features = [ 45 | "revision", 46 | "interrupt", 47 | "status", 48 | "dirwalk", 49 | ] } 50 | time = { workspace = true } 51 | vergen = { version = "10.0.0-beta.1", path = "../vergen", default-features = false } 52 | vergen-lib = { version = "1.0.0-beta.1", path = "../vergen-lib", features = ["git"] } 53 | 54 | [build-dependencies] 55 | rustversion = { workspace = true } 56 | 57 | [dev-dependencies] 58 | regex = { workspace = true } 59 | test_util = { path = "../test_util", features = ["repo", "unstable"] } 60 | serial_test = { workspace = true } 61 | temp-env = { workspace = true } 62 | 63 | [package.metadata.docs.rs] 64 | features = ["build", "cargo", "emit_and_set", "rustc", "si"] 65 | rustdoc-args = ["--cfg", "docsrs"] 66 | -------------------------------------------------------------------------------- /vergen-gix/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /vergen-gix/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /vergen-gix/README.md: -------------------------------------------------------------------------------- 1 | ../README.md -------------------------------------------------------------------------------- /vergen-gix/build.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | println!("cargo:rerun-if-changed=build.rs"); 3 | nightly(); 4 | beta(); 5 | stable(); 6 | } 7 | 8 | #[rustversion::nightly] 9 | fn nightly() { 10 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 11 | println!("cargo:rustc-cfg=nightly"); 12 | } 13 | 14 | #[rustversion::not(nightly)] 15 | fn nightly() { 16 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 17 | } 18 | 19 | #[rustversion::beta] 20 | fn beta() { 21 | println!("cargo:rustc-check-cfg=cfg(beta)"); 22 | println!("cargo:rustc-cfg=beta"); 23 | } 24 | 25 | #[rustversion::not(beta)] 26 | fn beta() { 27 | println!("cargo:rustc-check-cfg=cfg(beta)"); 28 | } 29 | 30 | #[rustversion::stable] 31 | fn stable() { 32 | println!("cargo:rustc-check-cfg=cfg(stable)"); 33 | println!("cargo:rustc-cfg=stable"); 34 | } 35 | 36 | #[rustversion::not(stable)] 37 | fn stable() { 38 | println!("cargo:rustc-check-cfg=cfg(stable)"); 39 | } 40 | -------------------------------------------------------------------------------- /vergen-lib/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Jason Ozias "] 3 | categories = ["development-tools", "development-tools::build-utils"] 4 | description = "Common code used to support the vergen libraries" 5 | documentation = "https://docs.rs/vergen-lib" 6 | edition = "2024" 7 | homepage = "https://github.com/rustyhorde/vergen" 8 | keywords = ["cargo", "instructions", "build", "tool"] 9 | license = "MIT OR Apache-2.0" 10 | rust-version = "1.85.0" 11 | name = "vergen-lib" 12 | readme = "README.md" 13 | repository = "https://github.com/rustyhorde/vergen" 14 | version = "1.0.0-beta.1" 15 | 16 | [package.metadata.cargo-matrix] 17 | [[package.metadata.cargo-matrix.channel]] 18 | name = "default" 19 | always_deny = ["unstable"] 20 | 21 | [[package.metadata.cargo-matrix.channel]] 22 | name = "nightly" 23 | always_deny = [] 24 | always_include = ["unstable"] 25 | 26 | [[package.metadata.cargo-matrix.channel]] 27 | name = "llvm-cov" 28 | always_deny = ["emit_and_set"] 29 | always_include = ["unstable"] 30 | 31 | [features] 32 | default = [] 33 | build = [] 34 | cargo = [] 35 | emit_and_set = [] 36 | git = [] 37 | rustc = [] 38 | unstable = [] 39 | si = [] 40 | 41 | [dependencies] 42 | anyhow = { workspace = true } 43 | bon = { workspace = true } 44 | getset = "0.1.5" 45 | 46 | [build-dependencies] 47 | rustversion = { workspace = true } 48 | 49 | [dev-dependencies] 50 | serial_test = { workspace = true } 51 | temp-env = { workspace = true } 52 | test_util = { path = "../test_util", features = ["unstable"] } 53 | 54 | [package.metadata.docs.rs] 55 | features = ["build", "cargo", "git", "rustc", "si"] 56 | rustdoc-args = ["--cfg", "docsrs"] 57 | 58 | [lints.rust] 59 | unexpected_cfgs = { level = "allow", check-cfg = ['cfg(coverage,coverage_nightly)'] } -------------------------------------------------------------------------------- /vergen-lib/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /vergen-lib/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /vergen-lib/README.md: -------------------------------------------------------------------------------- 1 | # vergen-lib - Common code used to support the vergen libraries -------------------------------------------------------------------------------- /vergen-lib/build.rs: -------------------------------------------------------------------------------- 1 | pub fn main() { 2 | println!("cargo:rerun-if-changed=build.rs"); 3 | nightly(); 4 | beta(); 5 | stable(); 6 | } 7 | 8 | #[rustversion::nightly] 9 | fn nightly() { 10 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 11 | println!("cargo:rustc-cfg=nightly"); 12 | } 13 | 14 | #[rustversion::not(nightly)] 15 | fn nightly() { 16 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 17 | } 18 | 19 | #[rustversion::beta] 20 | fn beta() { 21 | println!("cargo:rustc-check-cfg=cfg(beta)"); 22 | println!("cargo:rustc-cfg=beta"); 23 | } 24 | 25 | #[rustversion::not(beta)] 26 | fn beta() { 27 | println!("cargo:rustc-check-cfg=cfg(beta)"); 28 | } 29 | 30 | #[rustversion::stable] 31 | fn stable() { 32 | println!("cargo:rustc-check-cfg=cfg(stable)"); 33 | println!("cargo:rustc-cfg=stable"); 34 | } 35 | 36 | #[rustversion::not(stable)] 37 | fn stable() { 38 | println!("cargo:rustc-check-cfg=cfg(stable)"); 39 | } 40 | -------------------------------------------------------------------------------- /vergen-lib/src/config.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 vergen developers 2 | // 3 | // Licensed under the Apache License, Version 2.0 4 | // or the MIT 5 | // license , at your 6 | // option. All files in the project carrying such notice may not be copied, 7 | // modified, or distributed except according to those terms. 8 | 9 | use bon::Builder; 10 | use getset::{CopyGetters, Getters}; 11 | 12 | // Common configuration structs 13 | 14 | /// git configuration for the `describe` output 15 | #[derive(Builder, Clone, Copy, CopyGetters, Debug, Eq, Getters, PartialEq)] 16 | pub struct Describe { 17 | /// Instead of using only the annotated tags, use any tag found in refs/tags namespace. 18 | #[builder(default = false)] 19 | #[getset(get_copy = "pub")] 20 | tags: bool, 21 | /// If the working tree has local modification "-dirty" is appended to it. 22 | #[builder(default = false)] 23 | #[getset(get_copy = "pub")] 24 | dirty: bool, 25 | /// Only consider tags matching the given glob pattern, excluding the "refs/tags/" prefix. 26 | #[getset(get = "pub")] 27 | match_pattern: Option<&'static str>, 28 | } 29 | 30 | /// git configuration for the `sha` output 31 | #[derive(Builder, Clone, Copy, CopyGetters, Debug, Eq, PartialEq)] 32 | pub struct Sha { 33 | /// Shortens the object name to a unique prefix 34 | #[builder(default = false)] 35 | #[getset(get_copy = "pub")] 36 | short: bool, 37 | } 38 | 39 | /// git configuration for the `dirty` output 40 | #[derive(Builder, Clone, Copy, CopyGetters, Debug, Eq, PartialEq)] 41 | pub struct Dirty { 42 | /// Should we include/ignore untracked files in deciding whether the repository is dirty. 43 | #[builder(default = false)] 44 | #[getset(get_copy = "pub")] 45 | include_untracked: bool, 46 | } 47 | -------------------------------------------------------------------------------- /vergen-lib/src/constants.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 vergen developers 2 | // 3 | // Licensed under the Apache License, Version 2.0 4 | // or the MIT 5 | // license , at your 6 | // option. All files in the project carrying such notice may not be copied, 7 | // modified, or distributed except according to those terms. 8 | 9 | //! Internal Constants 10 | 11 | /// The default idempotent output string 12 | pub const VERGEN_IDEMPOTENT_DEFAULT: &str = "VERGEN_IDEMPOTENT_OUTPUT"; 13 | 14 | #[cfg(any( 15 | feature = "build", 16 | feature = "cargo", 17 | feature = "git", 18 | feature = "rustc", 19 | feature = "si" 20 | ))] 21 | pub use self::features::*; 22 | 23 | /// The names used by [`crate::VergenKey`] for each enabled output 24 | #[cfg(any( 25 | feature = "build", 26 | feature = "cargo", 27 | feature = "git", 28 | feature = "rustc", 29 | feature = "si" 30 | ))] 31 | pub mod features { 32 | /// The timestamp of the current build 33 | #[cfg(feature = "build")] 34 | pub const BUILD_TIMESTAMP_NAME: &str = "VERGEN_BUILD_TIMESTAMP"; 35 | /// The date of the current build 36 | #[cfg(feature = "build")] 37 | pub const BUILD_DATE_NAME: &str = "VERGEN_BUILD_DATE"; 38 | 39 | /// The current branch name 40 | #[cfg(feature = "git")] 41 | pub const GIT_BRANCH_NAME: &str = "VERGEN_GIT_BRANCH"; 42 | /// The most recent commit author email address 43 | #[cfg(feature = "git")] 44 | pub const GIT_COMMIT_AUTHOR_EMAIL: &str = "VERGEN_GIT_COMMIT_AUTHOR_EMAIL"; 45 | /// The most recent commit author name 46 | #[cfg(feature = "git")] 47 | pub const GIT_COMMIT_AUTHOR_NAME: &str = "VERGEN_GIT_COMMIT_AUTHOR_NAME"; 48 | /// The commit count 49 | #[cfg(feature = "git")] 50 | pub const GIT_COMMIT_COUNT: &str = "VERGEN_GIT_COMMIT_COUNT"; 51 | /// The most recent commit message 52 | #[cfg(feature = "git")] 53 | pub const GIT_COMMIT_MESSAGE: &str = "VERGEN_GIT_COMMIT_MESSAGE"; 54 | /// The most recent commit date 55 | #[cfg(feature = "git")] 56 | pub const GIT_COMMIT_DATE_NAME: &str = "VERGEN_GIT_COMMIT_DATE"; 57 | /// The most recent commit timestamp 58 | #[cfg(feature = "git")] 59 | pub const GIT_COMMIT_TIMESTAMP_NAME: &str = "VERGEN_GIT_COMMIT_TIMESTAMP"; 60 | /// The output of git describe 61 | #[cfg(feature = "git")] 62 | pub const GIT_DESCRIBE_NAME: &str = "VERGEN_GIT_DESCRIBE"; 63 | /// The most recent commit SHA 64 | #[cfg(feature = "git")] 65 | pub const GIT_SHA_NAME: &str = "VERGEN_GIT_SHA"; 66 | /// The current dirty status 67 | #[cfg(feature = "git")] 68 | pub const GIT_DIRTY_NAME: &str = "VERGEN_GIT_DIRTY"; 69 | 70 | /// The channel of rustc used for the build (stable, beta, nightly) 71 | #[cfg(feature = "rustc")] 72 | pub const RUSTC_CHANNEL_NAME: &str = "VERGEN_RUSTC_CHANNEL"; 73 | /// The host triple of rustc used for the build 74 | #[cfg(feature = "rustc")] 75 | pub const RUSTC_HOST_TRIPLE_NAME: &str = "VERGEN_RUSTC_HOST_TRIPLE"; 76 | /// The version of rustc used for the build 77 | #[cfg(feature = "rustc")] 78 | pub const RUSTC_SEMVER_NAME: &str = "VERGEN_RUSTC_SEMVER"; 79 | /// The commit hash of rustc used for the build 80 | #[cfg(feature = "rustc")] 81 | pub const RUSTC_COMMIT_HASH: &str = "VERGEN_RUSTC_COMMIT_HASH"; 82 | /// The commit date of rustc used for the build 83 | #[cfg(feature = "rustc")] 84 | pub const RUSTC_COMMIT_DATE: &str = "VERGEN_RUSTC_COMMIT_DATE"; 85 | /// The LLVM version underlying rustc used for the build (if applicable) 86 | #[cfg(feature = "rustc")] 87 | pub const RUSTC_LLVM_VERSION: &str = "VERGEN_RUSTC_LLVM_VERSION"; 88 | 89 | /// The value of the `DEBUG` environment variable at build time 90 | #[cfg(feature = "cargo")] 91 | pub const CARGO_DEBUG: &str = "VERGEN_CARGO_DEBUG"; 92 | /// The current dependency list (potentiall filtered) 93 | #[cfg(feature = "cargo")] 94 | pub const CARGO_DEPENDENCIES: &str = "VERGEN_CARGO_DEPENDENCIES"; 95 | /// The value of the `CARGO_FEATURES` environment variable at build time 96 | #[cfg(feature = "cargo")] 97 | pub const CARGO_FEATURES: &str = "VERGEN_CARGO_FEATURES"; 98 | /// The value of the `OPT_LEVEL` environment variable at build time 99 | #[cfg(feature = "cargo")] 100 | pub const CARGO_OPT_LEVEL: &str = "VERGEN_CARGO_OPT_LEVEL"; 101 | /// The value of the `TARGET_TRIPLE` environment variable at build time 102 | #[cfg(feature = "cargo")] 103 | pub const CARGO_TARGET_TRIPLE: &str = "VERGEN_CARGO_TARGET_TRIPLE"; 104 | 105 | /// The system name 106 | #[cfg(feature = "si")] 107 | pub const SYSINFO_NAME: &str = "VERGEN_SYSINFO_NAME"; 108 | /// The OS version 109 | #[cfg(feature = "si")] 110 | pub const SYSINFO_OS_VERSION: &str = "VERGEN_SYSINFO_OS_VERSION"; 111 | /// The user that ran the build 112 | #[cfg(feature = "si")] 113 | pub const SYSINFO_USER: &str = "VERGEN_SYSINFO_USER"; 114 | /// The total memory on the system used to run the build 115 | #[cfg(feature = "si")] 116 | pub const SYSINFO_MEMORY: &str = "VERGEN_SYSINFO_TOTAL_MEMORY"; 117 | /// The CPU vender on the system used to run the build 118 | #[cfg(feature = "si")] 119 | pub const SYSINFO_CPU_VENDOR: &str = "VERGEN_SYSINFO_CPU_VENDOR"; 120 | /// The CPU core count on the system use to run the build 121 | #[cfg(feature = "si")] 122 | pub const SYSINFO_CPU_CORE_COUNT: &str = "VERGEN_SYSINFO_CPU_CORE_COUNT"; 123 | /// The CPU name on the system use to run the build 124 | #[cfg(feature = "si")] 125 | pub const SYSINFO_CPU_NAME: &str = "VERGEN_SYSINFO_CPU_NAME"; 126 | /// The CPU brand on the system use to run the build 127 | #[cfg(feature = "si")] 128 | pub const SYSINFO_CPU_BRAND: &str = "VERGEN_SYSINFO_CPU_BRAND"; 129 | /// The CPU frequency on the system use to run the build 130 | #[cfg(feature = "si")] 131 | pub const SYSINFO_CPU_FREQUENCY: &str = "VERGEN_SYSINFO_CPU_FREQUENCY"; 132 | } 133 | 134 | /// An empty list of names to use with [`crate::VergenKey`] when 135 | /// no features are enabled. 136 | #[cfg(not(any( 137 | feature = "build", 138 | feature = "cargo", 139 | feature = "git", 140 | feature = "rustc", 141 | feature = "si" 142 | )))] 143 | pub mod features {} 144 | 145 | #[cfg(all( 146 | test, 147 | any( 148 | feature = "build", 149 | feature = "cargo", 150 | feature = "git", 151 | feature = "rustc", 152 | feature = "si" 153 | ) 154 | ))] 155 | mod test { 156 | use super::*; 157 | 158 | #[cfg(feature = "build")] 159 | #[test] 160 | fn build_constants_dont_change() { 161 | // Build Constants 162 | assert_eq!(BUILD_TIMESTAMP_NAME, "VERGEN_BUILD_TIMESTAMP"); 163 | assert_eq!(BUILD_DATE_NAME, "VERGEN_BUILD_DATE"); 164 | } 165 | 166 | #[cfg(feature = "cargo")] 167 | #[test] 168 | fn cargo_constants_dont_change() { 169 | // cargo Constants 170 | assert_eq!(CARGO_TARGET_TRIPLE, "VERGEN_CARGO_TARGET_TRIPLE"); 171 | assert_eq!(CARGO_FEATURES, "VERGEN_CARGO_FEATURES"); 172 | } 173 | 174 | #[cfg(feature = "git")] 175 | #[test] 176 | fn git_constants_dont_change() { 177 | // git Constants 178 | assert_eq!(GIT_BRANCH_NAME, "VERGEN_GIT_BRANCH"); 179 | assert_eq!(GIT_COMMIT_AUTHOR_EMAIL, "VERGEN_GIT_COMMIT_AUTHOR_EMAIL"); 180 | assert_eq!(GIT_COMMIT_AUTHOR_NAME, "VERGEN_GIT_COMMIT_AUTHOR_NAME"); 181 | assert_eq!(GIT_COMMIT_COUNT, "VERGEN_GIT_COMMIT_COUNT"); 182 | assert_eq!(GIT_COMMIT_MESSAGE, "VERGEN_GIT_COMMIT_MESSAGE"); 183 | assert_eq!(GIT_COMMIT_DATE_NAME, "VERGEN_GIT_COMMIT_DATE"); 184 | assert_eq!(GIT_COMMIT_TIMESTAMP_NAME, "VERGEN_GIT_COMMIT_TIMESTAMP"); 185 | assert_eq!(GIT_DESCRIBE_NAME, "VERGEN_GIT_DESCRIBE"); 186 | assert_eq!(GIT_SHA_NAME, "VERGEN_GIT_SHA"); 187 | assert_eq!(GIT_DIRTY_NAME, "VERGEN_GIT_DIRTY"); 188 | } 189 | 190 | #[cfg(feature = "rustc")] 191 | #[test] 192 | fn rustc_constants_dont_change() { 193 | // rustc Constants 194 | assert_eq!(RUSTC_SEMVER_NAME, "VERGEN_RUSTC_SEMVER"); 195 | assert_eq!(RUSTC_CHANNEL_NAME, "VERGEN_RUSTC_CHANNEL"); 196 | assert_eq!(RUSTC_HOST_TRIPLE_NAME, "VERGEN_RUSTC_HOST_TRIPLE"); 197 | assert_eq!(RUSTC_COMMIT_HASH, "VERGEN_RUSTC_COMMIT_HASH"); 198 | assert_eq!(RUSTC_COMMIT_DATE, "VERGEN_RUSTC_COMMIT_DATE"); 199 | assert_eq!(RUSTC_LLVM_VERSION, "VERGEN_RUSTC_LLVM_VERSION"); 200 | } 201 | 202 | #[cfg(feature = "si")] 203 | #[test] 204 | fn sysinfo_constants_dont_change() { 205 | // sysinfo Constants 206 | assert_eq!(SYSINFO_NAME, "VERGEN_SYSINFO_NAME"); 207 | assert_eq!(SYSINFO_OS_VERSION, "VERGEN_SYSINFO_OS_VERSION"); 208 | assert_eq!(SYSINFO_USER, "VERGEN_SYSINFO_USER"); 209 | assert_eq!(SYSINFO_MEMORY, "VERGEN_SYSINFO_TOTAL_MEMORY"); 210 | assert_eq!(SYSINFO_CPU_VENDOR, "VERGEN_SYSINFO_CPU_VENDOR"); 211 | assert_eq!(SYSINFO_CPU_CORE_COUNT, "VERGEN_SYSINFO_CPU_CORE_COUNT"); 212 | assert_eq!(SYSINFO_CPU_NAME, "VERGEN_SYSINFO_CPU_NAME"); 213 | assert_eq!(SYSINFO_CPU_BRAND, "VERGEN_SYSINFO_CPU_BRAND"); 214 | assert_eq!(SYSINFO_CPU_FREQUENCY, "VERGEN_SYSINFO_CPU_FREQUENCY"); 215 | } 216 | } 217 | -------------------------------------------------------------------------------- /vergen-lib/src/entries.rs: -------------------------------------------------------------------------------- 1 | use crate::VergenKey; 2 | 3 | use anyhow::{Error, Result}; 4 | use std::collections::BTreeMap; 5 | 6 | /// The map used to emit `cargo:rustc-env=NAME=VALUE` cargo instructions 7 | pub type CargoRustcEnvMap = BTreeMap; 8 | /// The vector of strings used to emit `cargo:rerun-if-changed=VALUE` cargo instructions 9 | pub type CargoRerunIfChanged = Vec; 10 | /// The vector of strings used to emit `cargo:warning=VALUE` cargo instructions 11 | pub type CargoWarning = Vec; 12 | 13 | /// The default configuration to use when an issue has occured generating instructions 14 | #[derive(Debug)] 15 | pub struct DefaultConfig { 16 | /// Should idempotent output be generated? 17 | idempotent: bool, 18 | /// Should we fail if an error occurs or output idempotent values on error? 19 | fail_on_error: bool, 20 | /// The error that caused us to try default instruction output. 21 | error: Error, 22 | } 23 | 24 | impl DefaultConfig { 25 | /// Create a new [`DefaultConfig`] struct with the given values. 26 | #[must_use] 27 | pub fn new(idempotent: bool, fail_on_error: bool, error: Error) -> Self { 28 | Self { 29 | idempotent, 30 | fail_on_error, 31 | error, 32 | } 33 | } 34 | /// Should idempotent output be generated? 35 | #[must_use] 36 | pub fn idempotent(&self) -> &bool { 37 | &self.idempotent 38 | } 39 | /// Should we fail if an error occurs or output idempotent values on error? 40 | #[must_use] 41 | pub fn fail_on_error(&self) -> &bool { 42 | &self.fail_on_error 43 | } 44 | /// The error that caused us to try default instruction output. 45 | #[must_use] 46 | pub fn error(&self) -> &Error { 47 | &self.error 48 | } 49 | } 50 | 51 | /// This trait should be implemented to allow the `vergen` emitter 52 | /// to properly emit instructions for your feature. 53 | pub trait Add { 54 | /// Try to add instructions entries to the various given arguments. 55 | /// 56 | /// * Write to the `cargo_rustc_env` map to emit 'cargo:rustc-env=NAME=VALUE' instructions. 57 | /// * Write to the `cargo_rerun_if_changed` vector to emit 'cargo:rerun-if-changed=VALUE' instructions. 58 | /// * Write to the `cargo_warning` vector to emit 'cargo:warning=VALUE' instructions. 59 | /// 60 | /// # Errors 61 | /// 62 | /// If an error occurs, the `vergen` emitter will use `add_default_entries` to generate output. 63 | /// This assumes generating instructions may fail in some manner so a [`anyhow::Result`] is returned. 64 | /// 65 | fn add_map_entries( 66 | &self, 67 | idempotent: bool, 68 | cargo_rustc_env: &mut CargoRustcEnvMap, 69 | cargo_rerun_if_changed: &mut CargoRerunIfChanged, 70 | cargo_warning: &mut CargoWarning, 71 | ) -> Result<()>; 72 | 73 | /// Based on the given configuration, emit either default idempotent output or generate a failue. 74 | /// 75 | /// * Write to the `cargo_rustc_env` map to emit 'cargo:rustc-env=NAME=VALUE' instructions. 76 | /// * Write to the `cargo_rerun_if_changed` vector to emit 'cargo:rerun-if-changed=VALUE' instructions. 77 | /// * Write to the `cargo_warning` vector to emit 'cargo:warning=VALUE' instructions. 78 | /// 79 | /// # Errors 80 | /// 81 | /// This assumes generating instructions may fail in some manner so a [`anyhow::Result`] is returned. 82 | /// 83 | fn add_default_entries( 84 | &self, 85 | config: &DefaultConfig, 86 | cargo_rustc_env_map: &mut CargoRustcEnvMap, 87 | cargo_rerun_if_changed: &mut CargoRerunIfChanged, 88 | cargo_warning: &mut CargoWarning, 89 | ) -> Result<()>; 90 | } 91 | 92 | /// This trait should be implemented to allow the `vergen` emitter to properly emit your custom instructions. 93 | /// 94 | /// # Example 95 | /// ``` 96 | /// # use anyhow::Result; 97 | /// # use std::collections::BTreeMap; 98 | /// # use vergen_lib::{AddCustomEntries, CargoRerunIfChanged, CargoWarning, DefaultConfig}; 99 | /// #[derive(Default)] 100 | /// struct Custom {} 101 | /// 102 | /// impl AddCustomEntries<&str, &str> for Custom { 103 | /// fn add_calculated_entries( 104 | /// &self, 105 | /// _idempotent: bool, 106 | /// cargo_rustc_env_map: &mut BTreeMap<&str, &str>, 107 | /// _cargo_rerun_if_changed: &mut CargoRerunIfChanged, 108 | /// cargo_warning: &mut CargoWarning, 109 | /// ) -> Result<()> { 110 | /// cargo_rustc_env_map.insert("vergen-cl", "custom_instruction"); 111 | /// cargo_warning.push("custom instruction generated".to_string()); 112 | /// Ok(()) 113 | /// } 114 | /// 115 | /// fn add_default_entries( 116 | /// &self, 117 | /// _config: &DefaultConfig, 118 | /// _cargo_rustc_env_map: &mut BTreeMap<&str, &str>, 119 | /// _cargo_rerun_if_changed: &mut CargoRerunIfChanged, 120 | /// _cargo_warning: &mut CargoWarning, 121 | /// ) -> Result<()> { 122 | /// Ok(()) 123 | /// } 124 | /// } 125 | /// ``` 126 | /// ## Then in [`build.rs`] 127 | /// 128 | /// ```will_not_compile 129 | /// let build = BuildBuilder::all_build()?; 130 | /// let cargo = CargoBuilder::all_cargo()?; 131 | /// let gix = GixBuilder::all_git()?; 132 | /// let rustc = RustcBuilder::all_rustc()?; 133 | /// let si = SysinfoBuilder::all_sysinfo()?; 134 | /// Emitter::default() 135 | /// .add_instructions(&build)? 136 | /// .add_instructions(&cargo)? 137 | /// .add_instructions(&gix)? 138 | /// .add_instructions(&rustc)? 139 | /// .add_instructions(&si)? 140 | /// .add_custom_instructions(&Custom::default())? 141 | /// .emit() 142 | /// ``` 143 | pub trait AddCustom + Ord, V: Into> { 144 | /// Try to add instructions entries to the various given arguments. 145 | /// 146 | /// * Write to the `cargo_rustc_env` map to emit 'cargo:rustc-env=NAME=VALUE' instructions. 147 | /// * Write to the `cargo_rerun_if_changed` vector to emit 'cargo:rerun-if-changed=VALUE' instructions. 148 | /// * Write to the `cargo_warning` vector to emit 'cargo:warning=VALUE' instructions. 149 | /// 150 | /// # Errors 151 | /// 152 | /// If an error occurs, the `vergen` emitter will use `add_default_entries` to generate output. 153 | /// This assumes generating instructions may fail in some manner so a [`anyhow::Result`] is returned. 154 | /// 155 | fn add_calculated_entries( 156 | &self, 157 | idempotent: bool, 158 | cargo_rustc_env_map: &mut BTreeMap, 159 | cargo_rerun_if_changed: &mut CargoRerunIfChanged, 160 | cargo_warning: &mut CargoWarning, 161 | ) -> Result<()>; 162 | 163 | /// Based on the given configuration, emit either default idempotent output or generate a failue. 164 | /// 165 | /// * Write to the `cargo_rustc_env` map to emit 'cargo:rustc-env=NAME=VALUE' instructions. 166 | /// * Write to the `cargo_rerun_if_changed` vector to emit 'cargo:rerun-if-changed=VALUE' instructions. 167 | /// * Write to the `cargo_warning` vector to emit 'cargo:warning=VALUE' instructions. 168 | /// 169 | /// # Errors 170 | /// 171 | /// This assumes generating instructions may fail in some manner so a [`anyhow::Result`] is returned. 172 | /// 173 | fn add_default_entries( 174 | &self, 175 | config: &DefaultConfig, 176 | cargo_rustc_env_map: &mut BTreeMap, 177 | cargo_rerun_if_changed: &mut CargoRerunIfChanged, 178 | cargo_warning: &mut CargoWarning, 179 | ) -> Result<()>; 180 | } 181 | 182 | #[doc(hidden)] 183 | pub(crate) mod test_gen { 184 | use crate::{AddCustomEntries, CargoRerunIfChanged, CargoWarning}; 185 | use anyhow::{Result, anyhow}; 186 | use bon::Builder; 187 | use std::collections::BTreeMap; 188 | 189 | #[doc(hidden)] 190 | #[derive(Builder, Clone, Copy, Debug, Default)] 191 | pub struct CustomInsGen { 192 | #[builder(default = false)] 193 | fail: bool, 194 | } 195 | 196 | impl AddCustomEntries<&str, &str> for CustomInsGen { 197 | fn add_calculated_entries( 198 | &self, 199 | idempotent: bool, 200 | cargo_rustc_env_map: &mut BTreeMap<&str, &str>, 201 | _cargo_rerun_if_changed: &mut CargoRerunIfChanged, 202 | _cargo_warning: &mut CargoWarning, 203 | ) -> Result<()> { 204 | if self.fail { 205 | Err(anyhow!("We have failed")) 206 | } else { 207 | if idempotent { 208 | let _ = cargo_rustc_env_map.insert("test", "VERGEN_IDEMPOTENT_OUTPUT"); 209 | } else { 210 | let _ = cargo_rustc_env_map.insert("test", "value"); 211 | } 212 | Ok(()) 213 | } 214 | } 215 | 216 | fn add_default_entries( 217 | &self, 218 | config: &crate::DefaultConfig, 219 | cargo_rustc_env_map: &mut BTreeMap<&str, &str>, 220 | _cargo_rerun_if_changed: &mut CargoRerunIfChanged, 221 | _cargo_warning: &mut CargoWarning, 222 | ) -> Result<()> { 223 | if *config.fail_on_error() { 224 | let error = anyhow!(format!("{}", config.error())); 225 | Err(error) 226 | } else { 227 | let _ = cargo_rustc_env_map.insert("test", "VERGEN_IDEMPOTENT_OUTPUT"); 228 | Ok(()) 229 | } 230 | } 231 | } 232 | } 233 | 234 | #[cfg(test)] 235 | mod test { 236 | use super::DefaultConfig; 237 | use anyhow::{Result, anyhow}; 238 | use std::io::Write; 239 | 240 | #[test] 241 | fn default_config_debug() -> Result<()> { 242 | let config = DefaultConfig::new(true, true, anyhow!("blah")); 243 | let mut buf = vec![]; 244 | write!(buf, "{config:?}")?; 245 | assert!(!buf.is_empty()); 246 | Ok(()) 247 | } 248 | } 249 | -------------------------------------------------------------------------------- /vergen-lib/src/lib.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 vergen developers 2 | // 3 | // Licensed under the Apache License, Version 2.0 4 | // or the MIT 5 | // license , at your 6 | // option. All files in the project carrying such notice may not be copied, 7 | // modified, or distributed except according to those terms. 8 | 9 | //! # vergen-lib - Common structs, enums and constants used to support [`vergen`](https://docs.rs/vergen) 10 | //! 11 | 12 | // rustc lints 13 | #![cfg_attr( 14 | all(feature = "unstable", nightly), 15 | feature( 16 | multiple_supertrait_upcastable, 17 | must_not_suspend, 18 | non_exhaustive_omitted_patterns_lint, 19 | rustdoc_missing_doc_code_examples, 20 | strict_provenance_lints, 21 | supertrait_item_shadowing, 22 | unqualified_local_imports, 23 | ) 24 | )] 25 | #![cfg_attr(nightly, allow(single_use_lifetimes, unexpected_cfgs))] 26 | #![cfg_attr( 27 | nightly, 28 | deny( 29 | absolute_paths_not_starting_with_crate, 30 | ambiguous_glob_imports, 31 | ambiguous_glob_reexports, 32 | ambiguous_negative_literals, 33 | ambiguous_wide_pointer_comparisons, 34 | anonymous_parameters, 35 | array_into_iter, 36 | asm_sub_register, 37 | async_fn_in_trait, 38 | bad_asm_style, 39 | bare_trait_objects, 40 | boxed_slice_into_iter, 41 | break_with_label_and_loop, 42 | clashing_extern_declarations, 43 | closure_returning_async_block, 44 | coherence_leak_check, 45 | confusable_idents, 46 | const_evaluatable_unchecked, 47 | const_item_mutation, 48 | dangling_pointers_from_temporaries, 49 | dead_code, 50 | dependency_on_unit_never_type_fallback, 51 | deprecated, 52 | deprecated_in_future, 53 | deprecated_safe_2024, 54 | deprecated_where_clause_location, 55 | deref_into_dyn_supertrait, 56 | deref_nullptr, 57 | double_negations, 58 | drop_bounds, 59 | dropping_copy_types, 60 | dropping_references, 61 | duplicate_macro_attributes, 62 | dyn_drop, 63 | edition_2024_expr_fragment_specifier, 64 | elided_lifetimes_in_paths, 65 | elided_named_lifetimes, 66 | ellipsis_inclusive_range_patterns, 67 | explicit_outlives_requirements, 68 | exported_private_dependencies, 69 | ffi_unwind_calls, 70 | forbidden_lint_groups, 71 | forgetting_copy_types, 72 | forgetting_references, 73 | for_loops_over_fallibles, 74 | function_item_references, 75 | hidden_glob_reexports, 76 | if_let_rescope, 77 | impl_trait_overcaptures, 78 | impl_trait_redundant_captures, 79 | improper_ctypes, 80 | improper_ctypes_definitions, 81 | inline_no_sanitize, 82 | internal_features, 83 | invalid_from_utf8, 84 | invalid_macro_export_arguments, 85 | invalid_nan_comparisons, 86 | invalid_value, 87 | irrefutable_let_patterns, 88 | keyword_idents_2018, 89 | keyword_idents_2024, 90 | large_assignments, 91 | late_bound_lifetime_arguments, 92 | legacy_derive_helpers, 93 | let_underscore_drop, 94 | macro_use_extern_crate, 95 | map_unit_fn, 96 | meta_variable_misuse, 97 | missing_abi, 98 | missing_copy_implementations, 99 | missing_debug_implementations, 100 | missing_docs, 101 | missing_unsafe_on_extern, 102 | mixed_script_confusables, 103 | named_arguments_used_positionally, 104 | never_type_fallback_flowing_into_unsafe, 105 | no_mangle_generic_items, 106 | non_ascii_idents, 107 | non_camel_case_types, 108 | non_contiguous_range_endpoints, 109 | non_fmt_panics, 110 | non_local_definitions, 111 | non_shorthand_field_patterns, 112 | non_snake_case, 113 | non_upper_case_globals, 114 | noop_method_call, 115 | opaque_hidden_inferred_bound, 116 | out_of_scope_macro_calls, 117 | overlapping_range_endpoints, 118 | path_statements, 119 | private_bounds, 120 | private_interfaces, 121 | ptr_to_integer_transmute_in_consts, 122 | redundant_imports, 123 | redundant_lifetimes, 124 | redundant_semicolons, 125 | refining_impl_trait_internal, 126 | refining_impl_trait_reachable, 127 | renamed_and_removed_lints, 128 | repr_transparent_external_private_fields, 129 | rust_2021_incompatible_closure_captures, 130 | rust_2021_incompatible_or_patterns, 131 | rust_2021_prefixes_incompatible_syntax, 132 | rust_2021_prelude_collisions, 133 | rust_2024_guarded_string_incompatible_syntax, 134 | rust_2024_incompatible_pat, 135 | rust_2024_prelude_collisions, 136 | self_constructor_from_outer_item, 137 | semicolon_in_expressions_from_macros, 138 | single_use_lifetimes, 139 | special_module_name, 140 | stable_features, 141 | static_mut_refs, 142 | suspicious_double_ref_op, 143 | tail_expr_drop_order, 144 | trivial_bounds, 145 | trivial_casts, 146 | trivial_numeric_casts, 147 | type_alias_bounds, 148 | tyvar_behind_raw_pointer, 149 | uncommon_codepoints, 150 | unconditional_recursion, 151 | uncovered_param_in_projection, 152 | unexpected_cfgs, 153 | unfulfilled_lint_expectations, 154 | ungated_async_fn_track_caller, 155 | uninhabited_static, 156 | unit_bindings, 157 | unknown_lints, 158 | unknown_or_malformed_diagnostic_attributes, 159 | unnameable_test_items, 160 | unnameable_types, 161 | unpredictable_function_pointer_comparisons, 162 | unreachable_code, 163 | unreachable_patterns, 164 | unreachable_pub, 165 | unsafe_attr_outside_unsafe, 166 | unsafe_op_in_unsafe_fn, 167 | unstable_name_collisions, 168 | unstable_syntax_pre_expansion, 169 | unsupported_fn_ptr_calling_conventions, 170 | unused_allocation, 171 | unused_assignments, 172 | unused_associated_type_bounds, 173 | unused_attributes, 174 | unused_braces, 175 | unused_comparisons, 176 | unused_crate_dependencies, 177 | unused_doc_comments, 178 | unused_extern_crates, 179 | unused_features, 180 | unused_import_braces, 181 | unused_imports, 182 | unused_labels, 183 | unused_lifetimes, 184 | unused_macro_rules, 185 | unused_macros, 186 | unused_must_use, 187 | unused_mut, 188 | unused_parens, 189 | unused_qualifications, 190 | unused_results, 191 | unused_unsafe, 192 | unused_variables, 193 | useless_ptr_null_checks, 194 | uses_power_alignment, 195 | variant_size_differences, 196 | wasm_c_abi, 197 | while_true, 198 | ) 199 | )] 200 | // If nightly and unstable, allow `incomplete_features` and `unstable_features` 201 | #![cfg_attr( 202 | all(feature = "unstable", nightly), 203 | allow(incomplete_features, unstable_features) 204 | )] 205 | // If nightly and not unstable, deny `incomplete_features` and `unstable_features` 206 | #![cfg_attr( 207 | all(not(feature = "unstable"), nightly), 208 | deny(incomplete_features, unstable_features) 209 | )] 210 | #![cfg_attr(all(not(feature = "emit_and_set"), nightly), deny(unsafe_code))] 211 | #![cfg_attr(all(feature = "emit_and_set", nightly), allow(unsafe_code))] 212 | // The unstable lints 213 | #![cfg_attr( 214 | all(feature = "unstable", nightly), 215 | deny( 216 | fuzzy_provenance_casts, 217 | lossy_provenance_casts, 218 | multiple_supertrait_upcastable, 219 | must_not_suspend, 220 | non_exhaustive_omitted_patterns, 221 | supertrait_item_shadowing_definition, 222 | supertrait_item_shadowing_usage, 223 | unqualified_local_imports, 224 | ) 225 | )] 226 | // clippy lints 227 | #![cfg_attr(nightly, deny(clippy::all, clippy::pedantic))] 228 | #![cfg_attr(nightly, allow(clippy::ref_option_ref))] 229 | // rustdoc lints 230 | #![cfg_attr( 231 | nightly, 232 | deny( 233 | rustdoc::bare_urls, 234 | rustdoc::broken_intra_doc_links, 235 | rustdoc::invalid_codeblock_attributes, 236 | rustdoc::invalid_html_tags, 237 | rustdoc::missing_crate_level_docs, 238 | rustdoc::private_doc_tests, 239 | rustdoc::private_intra_doc_links, 240 | ) 241 | )] 242 | #![cfg_attr( 243 | all(nightly, feature = "unstable"), 244 | deny(rustdoc::missing_doc_code_examples) 245 | )] 246 | #![cfg_attr(all(doc, nightly), feature(doc_auto_cfg))] 247 | #![cfg_attr(all(docsrs, nightly), feature(doc_cfg))] 248 | #![cfg_attr(coverage_nightly, feature(coverage_attribute))] 249 | 250 | #[cfg(test)] 251 | use {temp_env as _, test_util as _}; 252 | 253 | mod config; 254 | pub mod constants; 255 | mod emitter; 256 | mod entries; 257 | mod keys; 258 | mod utils; 259 | 260 | pub use self::config::Describe; 261 | pub use self::config::Dirty; 262 | pub use self::config::Sha; 263 | pub use self::emitter::Emitter; 264 | pub use self::entries::Add as AddEntries; 265 | pub use self::entries::AddCustom as AddCustomEntries; 266 | pub use self::entries::CargoRerunIfChanged; 267 | pub use self::entries::CargoRustcEnvMap; 268 | pub use self::entries::CargoWarning; 269 | pub use self::entries::DefaultConfig; 270 | #[doc(hidden)] 271 | pub use self::entries::test_gen::CustomInsGen; 272 | pub use self::keys::vergen_key::VergenKey; 273 | pub use self::utils::add_default_map_entry; 274 | pub use self::utils::add_map_entry; 275 | pub use self::utils::count_idempotent; 276 | -------------------------------------------------------------------------------- /vergen-lib/src/utils.rs: -------------------------------------------------------------------------------- 1 | use crate::{CargoRustcEnvMap, CargoWarning, VergenKey, constants::VERGEN_IDEMPOTENT_DEFAULT}; 2 | use std::env; 3 | 4 | /// Add a [`VergenKey`] entry as a default string into the [`CargoRustcEnvMap`]. 5 | /// The value is either from an environment variable override or [`crate::constants::VERGEN_IDEMPOTENT_DEFAULT`] 6 | /// 7 | /// # Example 8 | /// ``` 9 | /// # use std::collections::BTreeMap; 10 | /// # use temp_env::with_var; 11 | /// # use vergen_lib::{add_default_map_entry, CargoRustcEnvMap, CargoWarning, VergenKey}; 12 | /// with_var("VERGEN_BUILD_DATE", Some("my own date"), || { 13 | /// let mut map: CargoRustcEnvMap = BTreeMap::new(); 14 | /// let mut warning: CargoWarning = vec![]; 15 | #[cfg_attr( 16 | feature = "build", 17 | doc = r" add_default_map_entry(false, VergenKey::BuildDate, &mut map, &mut warning); 18 | assert_eq!(1, map.len()); 19 | assert_eq!(1, warning.len());" 20 | )] 21 | /// }); 22 | /// ``` 23 | /// 24 | pub fn add_default_map_entry( 25 | idempotent: bool, 26 | key: VergenKey, 27 | map: &mut CargoRustcEnvMap, 28 | warnings: &mut CargoWarning, 29 | ) { 30 | if let Ok(value) = env::var(key.name()) { 31 | add_map_entry(key, value, map); 32 | warnings.push(format!("{} overidden", key.name())); 33 | } else if idempotent { 34 | add_map_entry(key, VERGEN_IDEMPOTENT_DEFAULT, map); 35 | warnings.push(format!("{} set to default", key.name())); 36 | } else { 37 | warnings.push(format!("Unable to set {}", key.name())); 38 | } 39 | } 40 | 41 | /// Add a [`VergenKey`] entry as a string into the [`CargoRustcEnvMap`]. 42 | /// 43 | /// # Example 44 | /// ``` 45 | /// # use std::collections::BTreeMap; 46 | /// # use vergen_lib::{add_map_entry, CargoRustcEnvMap, VergenKey}; 47 | /// let mut map: CargoRustcEnvMap = BTreeMap::new(); 48 | #[cfg_attr( 49 | feature = "build", 50 | doc = r#"add_map_entry(VergenKey::BuildDate, "test", &mut map); 51 | assert_eq!(1, map.len());"# 52 | )] 53 | /// ``` 54 | /// 55 | pub fn add_map_entry(key: VergenKey, value: T, map: &mut CargoRustcEnvMap) 56 | where 57 | T: Into, 58 | { 59 | let _old = map.insert(key, value.into()); 60 | } 61 | 62 | /// Count the number of idempotent entries in a [`CargoRustcEnvMap`] 63 | /// 64 | /// **NOTE** - This is mainly used for testing. 65 | /// 66 | /// # Example 67 | /// 68 | /// ``` 69 | /// # use std::collections::BTreeMap; 70 | /// # use vergen_lib::{count_idempotent, CargoRustcEnvMap, VergenKey, constants::VERGEN_IDEMPOTENT_DEFAULT}; 71 | /// # 72 | /// let mut map: CargoRustcEnvMap = BTreeMap::new(); 73 | /// assert_eq!(0, count_idempotent(&map)); 74 | #[cfg_attr( 75 | feature = "build", 76 | doc = r"_ = map.insert(VergenKey::BuildDate, VERGEN_IDEMPOTENT_DEFAULT.to_string());" 77 | )] 78 | #[cfg_attr(feature = "build", doc = r"assert_eq!(1, count_idempotent(&map));")] 79 | /// ``` 80 | /// 81 | #[must_use] 82 | pub fn count_idempotent(map: &CargoRustcEnvMap) -> usize { 83 | map.values() 84 | .filter(|x| *x == VERGEN_IDEMPOTENT_DEFAULT) 85 | .count() 86 | } 87 | -------------------------------------------------------------------------------- /vergen-pretty/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Jason Ozias "] 3 | categories = ["development-tools", "development-tools::build-utils"] 4 | description = "Output vergen information in a formatted manner" 5 | documentation = "https://docs.rs/vergen-pretty" 6 | edition = "2024" 7 | homepage = "https://github.com/rustyhorde/vergen" 8 | keywords = ["cargo", "instructions", "build", "tool"] 9 | license = "MIT OR Apache-2.0" 10 | rust-version = "1.85.0" 11 | name = "vergen-pretty" 12 | readme = "README.md" 13 | repository = "https://github.com/rustyhorde/vergen" 14 | version = "1.0.1" 15 | 16 | [package.metadata.cargo-matrix] 17 | [[package.metadata.cargo-matrix.channel]] 18 | name = "default" 19 | always_deny = ["unstable"] 20 | always_include = ["__vergen_test"] 21 | 22 | [[package.metadata.cargo-matrix.channel]] 23 | name = "nightly" 24 | always_deny = [] 25 | always_include = ["__vergen_test", "unstable"] 26 | 27 | [[package.metadata.cargo-matrix.channel]] 28 | name = "nightly-empty" 29 | always_deny = [] 30 | always_include = ["__vergen_empty_test", "unstable"] 31 | 32 | [features] 33 | default = [] 34 | unstable = ["vergen-gix/unstable"] 35 | color = ["console"] 36 | header = ["console", "rand"] 37 | trace = ["tracing"] 38 | __vergen_test = ["vergen-gix", "vergen-gix/unstable"] 39 | __vergen_empty_test = ["vergen-gix", "vergen-gix/unstable"] 40 | 41 | [dependencies] 42 | anyhow = { workspace = true } 43 | bon = { workspace = true } 44 | console = { version = "0.15.11", optional = true } 45 | convert_case = "0.8.0" 46 | rand = { workspace = true, optional = true } 47 | serde = { version = "1.0.219", features = ["derive"], optional = true } 48 | tracing = { version = "0.1.41", features = [ 49 | "max_level_trace", 50 | "release_max_level_trace", 51 | ], optional = true } 52 | 53 | [build-dependencies] 54 | anyhow = { workspace = true } 55 | rustversion = { workspace = true } 56 | vergen-gix = { version = "2.0.0-beta.1", path = "../vergen-gix", features = [ 57 | "build", 58 | "cargo", 59 | "rustc", 60 | "si", 61 | ], optional = true } 62 | 63 | [dev-dependencies] 64 | regex = { workspace = true } 65 | serde_json = "1.0.140" 66 | tracing-subscriber = { version = "0.3.19", features = ["fmt"] } 67 | 68 | [package.metadata.docs.rs] 69 | features = ["color", "header", "serde", "trace"] 70 | rustdoc-args = ["--cfg", "docsrs"] 71 | -------------------------------------------------------------------------------- /vergen-pretty/LICENSE-APACHE: -------------------------------------------------------------------------------- 1 | ../LICENSE-APACHE -------------------------------------------------------------------------------- /vergen-pretty/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | ../LICENSE-MIT -------------------------------------------------------------------------------- /vergen-pretty/README.md: -------------------------------------------------------------------------------- 1 | # vergen-pretty 2 | A pretty printer for `vergen` generated environment variables -------------------------------------------------------------------------------- /vergen-pretty/build.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use std::env; 3 | #[cfg(all(feature = "__vergen_empty_test", not(feature = "__vergen_test")))] 4 | use vergen_gix::Emitter; 5 | #[cfg(all(feature = "__vergen_test", not(feature = "__vergen_empty_test")))] 6 | use { 7 | std::collections::BTreeMap, 8 | vergen_gix::{ 9 | AddCustomEntries, Build, Cargo, CargoRerunIfChanged, CargoWarning, DefaultConfig, Emitter, 10 | Gix, Rustc, Sysinfo, 11 | }, 12 | }; 13 | 14 | fn main() -> Result<()> { 15 | println!("cargo:rerun-if-changed=build.rs"); 16 | nightly(); 17 | beta(); 18 | stable(); 19 | setup_env() 20 | } 21 | 22 | fn setup_env() -> Result<()> { 23 | if env::var("CARGO_FEATURE___VERGEN_TEST").is_ok() { 24 | emit()?; 25 | } 26 | Ok(()) 27 | } 28 | 29 | #[cfg(all(feature = "__vergen_test", feature = "__vergen_empty_test"))] 30 | fn emit() -> Result<()> { 31 | Ok(()) 32 | } 33 | 34 | #[cfg(not(any(feature = "__vergen_test", feature = "__vergen_empty_test")))] 35 | fn emit() -> Result<()> { 36 | Ok(()) 37 | } 38 | 39 | #[cfg(all(feature = "__vergen_test", not(feature = "__vergen_empty_test")))] 40 | #[derive(Default)] 41 | struct Custom {} 42 | 43 | #[cfg(all(feature = "__vergen_test", not(feature = "__vergen_empty_test")))] 44 | impl AddCustomEntries<&str, &str> for Custom { 45 | fn add_calculated_entries( 46 | &self, 47 | _idempotent: bool, 48 | cargo_rustc_env_map: &mut BTreeMap<&str, &str>, 49 | _cargo_rerun_if_changed: &mut CargoRerunIfChanged, 50 | cargo_warning: &mut CargoWarning, 51 | ) -> Result<()> { 52 | cargo_rustc_env_map.insert("vergen-cl", "custom_instruction"); 53 | cargo_warning.push("custom instruction generated".to_string()); 54 | Ok(()) 55 | } 56 | 57 | fn add_default_entries( 58 | &self, 59 | _config: &DefaultConfig, 60 | _cargo_rustc_env_map: &mut BTreeMap<&str, &str>, 61 | _cargo_rerun_if_changed: &mut CargoRerunIfChanged, 62 | _cargo_warning: &mut CargoWarning, 63 | ) -> Result<()> { 64 | Ok(()) 65 | } 66 | } 67 | 68 | #[cfg(all(feature = "__vergen_test", not(feature = "__vergen_empty_test")))] 69 | fn emit() -> Result<()> { 70 | println!("cargo:warning=VERGEN TEST ENABLED!"); 71 | let build = Build::all_build(); 72 | let cargo = Cargo::all_cargo(); 73 | let gix = Gix::all_git(); 74 | let rustc = Rustc::all_rustc(); 75 | let si = Sysinfo::all_sysinfo(); 76 | Emitter::default() 77 | .add_instructions(&build)? 78 | .add_instructions(&cargo)? 79 | .add_instructions(&gix)? 80 | .add_instructions(&rustc)? 81 | .add_instructions(&si)? 82 | .add_custom_instructions(&Custom::default())? 83 | .emit() 84 | } 85 | 86 | #[cfg(all(not(feature = "__vergen_test"), feature = "__vergen_empty_test"))] 87 | fn emit() -> Result<()> { 88 | println!("cargo:warning=VERGEN EMPTY TEST ENABLED!"); 89 | Emitter::default().emit() 90 | } 91 | 92 | #[rustversion::nightly] 93 | fn nightly() { 94 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 95 | println!("cargo:rustc-cfg=nightly"); 96 | } 97 | 98 | #[rustversion::not(nightly)] 99 | fn nightly() { 100 | println!("cargo:rustc-check-cfg=cfg(nightly)"); 101 | } 102 | 103 | #[rustversion::beta] 104 | fn beta() { 105 | println!("cargo:rustc-check-cfg=cfg(beta)"); 106 | println!("cargo:rustc-cfg=beta"); 107 | } 108 | 109 | #[rustversion::not(beta)] 110 | fn beta() { 111 | println!("cargo:rustc-check-cfg=cfg(beta)"); 112 | } 113 | 114 | #[rustversion::stable] 115 | fn stable() { 116 | println!("cargo:rustc-check-cfg=cfg(stable)"); 117 | println!("cargo:rustc-cfg=stable"); 118 | } 119 | 120 | #[rustversion::not(stable)] 121 | fn stable() { 122 | println!("cargo:rustc-check-cfg=cfg(stable)"); 123 | } 124 | -------------------------------------------------------------------------------- /vergen-pretty/src/pretty/feature/color.rs: -------------------------------------------------------------------------------- 1 | // Copyright (c) 2022 vergen developers 2 | // 3 | // Licensed under the Apache License, Version 2.0 4 | // or the MIT 5 | // license , at your 6 | // option. All files in the project carrying such notice may not be copied, 7 | // modified, or distributed except according to those terms. 8 | 9 | use crate::{Prefix, Suffix, pretty::Pretty}; 10 | use anyhow::Result; 11 | use console::Style; 12 | use std::{io::Write, sync::LazyLock}; 13 | 14 | pub(crate) static BOLD_BLUE: LazyLock