├── .cargo-husky
└── hooks
│ └── commit-msg
├── .cargo
└── config.toml
├── .github
├── banner.png
└── workflows
│ └── test.yml
├── .gitignore
├── .rustfmt.toml
├── CHANGELOG.md
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── README.md
├── cliff.toml
├── committed.toml
├── deny.toml
├── rust-toolchain.toml
├── src
├── binary.rs
├── cargo_config.rs
├── cli.rs
├── lib.rs
├── main.rs
├── metadata.rs
├── metadata_test.rs
└── shims.rs
├── tests
├── binary_test.rs
├── cargo_config_test.rs
├── cli_integration_test.rs
└── shims_test.rs
└── tools
└── cargo-bin
├── Cargo.toml
└── src
└── main.rs
/.cargo-husky/hooks/commit-msg:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | set -e
4 |
5 | cargo bin committed --fixup --wip --commit-file $1
6 |
--------------------------------------------------------------------------------
/.cargo/config.toml:
--------------------------------------------------------------------------------
1 | [alias]
2 | bin = ["run", "--package", "cargo-bin", "--"]
3 | cmd = ["bin", "cargo-cmd"]
4 | deny = ["bin", "cargo-deny"]
5 | gha = ["bin", "cargo-gha"]
6 | insta = ["bin", "cargo-insta"]
7 | llvm-cov = ["bin", "cargo-llvm-cov"]
8 | nextest = ["bin", "cargo-nextest"]
9 | watch = ["bin", "cargo-watch"]
10 |
11 | [env]
12 | BINSTALL_STRATEGIES = "crate-meta-data,compile"
13 |
14 | [net]
15 | git-fetch-with-cli = true
16 |
--------------------------------------------------------------------------------
/.github/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dustinblackman/cargo-run-bin/991dda0185c6fad71f549cfb078bbeb33433aa34/.github/banner.png
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | on: [push, pull_request]
2 |
3 | name: ci
4 |
5 | jobs:
6 | test_coverage:
7 | name: cargo-run-bin
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@v2
11 | - uses: actions-rs/toolchain@v1
12 | with:
13 | toolchain: stable
14 | - uses: Swatinem/rust-cache@v2
15 | with:
16 | cache-directories: ".bin"
17 |
18 | - name: Install deps
19 | run: |
20 | cargo bin --build
21 | cargo cmd setup-nightly
22 | - name: Lint
23 | run: cargo cmd lint
24 | - name: Test
25 | run: cargo cmd test-coverage-lcov
26 |
27 | - name: Coveralls
28 | uses: coverallsapp/github-action@master
29 | with:
30 | github-token: ${{ secrets.GITHUB_TOKEN }}
31 | path-to-lcov: ./lcov.info
32 |
33 | test:
34 | name: cargo-run-bin
35 | strategy:
36 | matrix:
37 | os: [macos-latest, windows-latest]
38 | runs-on: ${{ matrix.os }}
39 | steps:
40 | - uses: actions/checkout@v2
41 | - uses: actions-rs/toolchain@v1
42 | with:
43 | toolchain: stable
44 | - uses: Swatinem/rust-cache@v2
45 | with:
46 | cache-directories: ".bin"
47 | - name: Install deps
48 | run: |
49 | cargo nextest --help
50 | - name: Test
51 | run: |
52 | cargo build
53 | cargo nextest run
54 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 | /.bin
3 | /.tmp
4 | .gha/
5 | *.profraw
6 | lcov.info
7 | .idea/
8 |
--------------------------------------------------------------------------------
/.rustfmt.toml:
--------------------------------------------------------------------------------
1 | edition = "2021"
2 | force_multiline_blocks = true
3 | group_imports = "StdExternalCrate"
4 | imports_granularity = "Item"
5 | imports_layout = "HorizontalVertical"
6 | normalize_comments = true
7 | wrap_comments = true
8 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | All notable changes to this project will be documented in this file.
4 |
5 | ## [1.7.4] - 2024-11-25
6 | [v1.7.3..v1.7.4](https://github.com/dustinblackman/cargo-run-bin/compare/v1.7.3..v1.7.4)
7 |
8 |
9 | ### 🐛 Bug Fixes
10 |
11 | - Handle plain strings in --sync-aliases ([#25](https://github.com/dustinblackman/cargo-run-bin/issues/25)) - ([3c4d168](https://github.com/dustinblackman/cargo-run-bin/commit/3c4d168f34bf19e2da1099b6351f00b0ced2383c))
12 |
13 | ## [1.7.3] - 2024-07-05
14 | [v1.7.2..v1.7.3](https://github.com/dustinblackman/cargo-run-bin/compare/v1.7.2..v1.7.3)
15 |
16 |
17 | ### ⛰️ Features
18 |
19 | - Release v1.7.3 - ([c6bd9ec](https://github.com/dustinblackman/cargo-run-bin/commit/c6bd9ecf95fdc54c955090837b57d6fdca82b7d1))
20 |
21 | ### 🐛 Bug Fixes
22 |
23 | - Fallback to sh for non POSIX shells - ([7281bbb](https://github.com/dustinblackman/cargo-run-bin/commit/7281bbbf0a15b043d66e8f9f307485e210877df0))
24 |
25 | ### 📚 Documentation
26 |
27 | - Add distro packages section ([#22](https://github.com/dustinblackman/cargo-run-bin/issues/22)) - ([7e8378c](https://github.com/dustinblackman/cargo-run-bin/commit/7e8378c0ebff7c044e475407583ed8caf6bf2ec0))
28 | - Update version in README - ([42f87f9](https://github.com/dustinblackman/cargo-run-bin/commit/42f87f989cda444b841608db79c83cec2435a618))
29 |
30 | ### ⚙️ Miscellaneous Tasks
31 |
32 | - Fix lint - ([a8a5d45](https://github.com/dustinblackman/cargo-run-bin/commit/a8a5d452f81eb29483f584d4bc636cfe2393386c))
33 | - Drop owo - ([1dd54c4](https://github.com/dustinblackman/cargo-run-bin/commit/1dd54c478e35f22e4ba7fd1e0d46c100ecd64b62))
34 | - Update bin deps - ([33a2c0f](https://github.com/dustinblackman/cargo-run-bin/commit/33a2c0ff5694f75e9ddc7af8f65b223ab090a32f))
35 | - Drop dprint - ([02a968f](https://github.com/dustinblackman/cargo-run-bin/commit/02a968fc095cf8afc1615ea4cd4e936b4fc1e7e6))
36 | - Update binstall - ([ea0de75](https://github.com/dustinblackman/cargo-run-bin/commit/ea0de75ef4b0ff8d4c99ce3ab0cdd051da9f7006))
37 | - Update cargo-gha to latest - ([0dd4f2d](https://github.com/dustinblackman/cargo-run-bin/commit/0dd4f2d23d5909374f4513424490ff887a41d742))
38 |
39 | ## [1.7.2] - 2024-01-02
40 | [v1.7.1..v1.7.2](https://github.com/dustinblackman/cargo-run-bin/compare/v1.7.1..v1.7.2)
41 |
42 |
43 | ### ⛰️ Features
44 |
45 | - Release v1.7.2 - ([d11b188](https://github.com/dustinblackman/cargo-run-bin/commit/d11b1885a946214e4027a4f564f108b93c0ef0ea))
46 |
47 | ### ⚙️ Miscellaneous Tasks
48 |
49 | - Reduce MSRV - ([813f0bc](https://github.com/dustinblackman/cargo-run-bin/commit/813f0bc35ece0092cf04be043cc89571dea12ff2))
50 | - Remove version pinning - ([d466351](https://github.com/dustinblackman/cargo-run-bin/commit/d466351f0ea2098d063959b63585d24c9fd0e06d))
51 |
52 | ## [1.7.1] - 2024-01-01
53 | [v1.7.0..v1.7.1](https://github.com/dustinblackman/cargo-run-bin/compare/v1.7.0..v1.7.1)
54 |
55 |
56 | ### ⛰️ Features
57 |
58 | - Release v1.7.1 - ([c4c0861](https://github.com/dustinblackman/cargo-run-bin/commit/c4c0861672c77e0315070e30cf86719fa8e377b9))
59 |
60 | ### 🐛 Bug Fixes
61 |
62 | - Version flag, no parameters - ([e00ebe3](https://github.com/dustinblackman/cargo-run-bin/commit/e00ebe3c93367df53c91a6eb08fe3e8dc6e9fda8))
63 |
64 | ## [1.7.0] - 2024-01-01
65 | [v1.6.1..v1.7.0](https://github.com/dustinblackman/cargo-run-bin/compare/v1.6.1..v1.7.0)
66 |
67 |
68 | ### ⛰️ Features
69 |
70 | - Release v1.7.0 - ([416012f](https://github.com/dustinblackman/cargo-run-bin/commit/416012fa4cf20bc8c1a233a76f738c71c25e7d08))
71 | - Add get_shim_paths - ([fd60a88](https://github.com/dustinblackman/cargo-run-bin/commit/fd60a88054b194cd56e71faaff57044f47c7ce7f))
72 | - Add docs and features to support library usage - ([e180db6](https://github.com/dustinblackman/cargo-run-bin/commit/e180db69aee09faff006435fb83da3c59155f1d8))
73 |
74 | ### 🐛 Bug Fixes
75 |
76 | - Show help when no args are passed - ([6951082](https://github.com/dustinblackman/cargo-run-bin/commit/69510826e8c144093aeb0bfb7eb20475028e2d9d))
77 |
78 | ### 🚜 Refactor
79 |
80 | - Run tests as integration test ([#17](https://github.com/dustinblackman/cargo-run-bin/issues/17)) - ([4c5c49a](https://github.com/dustinblackman/cargo-run-bin/commit/4c5c49aeff217333024945d51f5483160c8be8ec))
81 | - Run tests as integration test - ([1e51847](https://github.com/dustinblackman/cargo-run-bin/commit/1e518477918de1d900702134b604f8a10d7ad265))
82 |
83 | ### 🧪 Testing
84 |
85 | - Shims imports - ([ca5da68](https://github.com/dustinblackman/cargo-run-bin/commit/ca5da684618025b4ea19fa6699c5978d9e67298a))
86 | - Move artifacts out of target - ([2f2fd57](https://github.com/dustinblackman/cargo-run-bin/commit/2f2fd579b60d0b5639c83dc7dc7dc8bd9cb337a9))
87 |
88 | ### ⚙️ Miscellaneous Tasks
89 |
90 | - Merge branch 'lib-support' - ([c21ce48](https://github.com/dustinblackman/cargo-run-bin/commit/c21ce487ccbf72626f32a54e71fac531905a2a61))
91 | - Fix warning on Windows builds - ([cadddd7](https://github.com/dustinblackman/cargo-run-bin/commit/cadddd77d84a072b62fdd6281cee4d87136d3539))
92 | - Revert unit test move - ([cfb552e](https://github.com/dustinblackman/cargo-run-bin/commit/cfb552ebf08403dda681f8c4b5b2cb5c811b0173))
93 | - Lint - ([834d089](https://github.com/dustinblackman/cargo-run-bin/commit/834d0898739fe86e47f5fa9f901b50dbcb041797))
94 | - Fix the rust-version field in Cargo.toml ([#19](https://github.com/dustinblackman/cargo-run-bin/issues/19)) - ([23b2f39](https://github.com/dustinblackman/cargo-run-bin/commit/23b2f398f1cbff666384089bf88bb16430630ba7))
95 |
96 | ## [1.6.1] - 2023-12-16
97 | [v1.6.0..v1.6.1](https://github.com/dustinblackman/cargo-run-bin/compare/v1.6.0..v1.6.1)
98 |
99 |
100 | ### ⛰️ Features
101 |
102 | - Release v1.6.1 - ([5d18ad7](https://github.com/dustinblackman/cargo-run-bin/commit/5d18ad7e827fb7bb0417218610a13a23bf7b5fd0))
103 |
104 | ### 🐛 Bug Fixes
105 |
106 | - Set MSRV - ([a5fc8ac](https://github.com/dustinblackman/cargo-run-bin/commit/a5fc8ac68dbba9f4f8a4b5d02bfd1e031bcdc56d))
107 | - Release command - ([032e97f](https://github.com/dustinblackman/cargo-run-bin/commit/032e97f52c612d68c4668d333e46cf56015b7eb6))
108 |
109 | ## [1.6.0] - 2023-12-01
110 | [v1.5.0..v1.6.0](https://github.com/dustinblackman/cargo-run-bin/compare/v1.5.0..v1.6.0)
111 |
112 |
113 | ### ⛰️ Features
114 |
115 | - Release v1.6.0 - ([fd34f2b](https://github.com/dustinblackman/cargo-run-bin/commit/fd34f2bd1713eefacd59d429d73d71da3c638325))
116 | - Merge branch 'windows' - ([a559325](https://github.com/dustinblackman/cargo-run-bin/commit/a5593250fc83922d9327a6896fed1c27625af73e))
117 | - Add Windows support - ([8e4a6cc](https://github.com/dustinblackman/cargo-run-bin/commit/8e4a6cc298a94190fe4ab209d9fa48a9a1afc791))
118 |
119 | ### ⚙️ Miscellaneous Tasks
120 |
121 | - Remove cargo-dist - ([553852d](https://github.com/dustinblackman/cargo-run-bin/commit/553852d8af838d7d5665e57ff5c4f8b9642c661e))
122 | - Cleanup CI - ([42403a2](https://github.com/dustinblackman/cargo-run-bin/commit/42403a2d311e346f78d5d28f729229639f69bb4b))
123 | - Add release script - ([2b10208](https://github.com/dustinblackman/cargo-run-bin/commit/2b10208d1e4a7be7fcf4a38a367525a82046ce2f))
124 | - Add banner - ([ddca279](https://github.com/dustinblackman/cargo-run-bin/commit/ddca279206775df41a98d05f476d579e6145c586))
125 |
126 | ## [1.5.0] - 2023-10-27
127 | [v1.4.1..v1.5.0](https://github.com/dustinblackman/cargo-run-bin/compare/v1.4.1..v1.5.0)
128 |
129 |
130 | ### ⛰️ Features
131 |
132 | - Support path in package source - ([d4c8c39](https://github.com/dustinblackman/cargo-run-bin/commit/d4c8c392e5f8b40e330cd5b596eda68b1d378e79))
133 |
134 | ### 🐛 Bug Fixes
135 |
136 | - Cargo.lock - ([505a155](https://github.com/dustinblackman/cargo-run-bin/commit/505a1559ae74893d55b9712ddafec0b57f7e1c5d))
137 | - Upgrade cargo-binstall dep - ([e2f746c](https://github.com/dustinblackman/cargo-run-bin/commit/e2f746c37f3954688fb535318d73cddc4255daf4))
138 | - Changelog - ([1ac6a3d](https://github.com/dustinblackman/cargo-run-bin/commit/1ac6a3d7cd331967c3bd5d9061d6b6862e33c030))
139 |
140 | ### 📚 Documentation
141 |
142 | - Add path - ([21fc3db](https://github.com/dustinblackman/cargo-run-bin/commit/21fc3db067967e36994e297cc09236c089ecc9b9))
143 |
144 | ### ⚙️ Miscellaneous Tasks
145 |
146 | - Release cargo-run-bin version 1.5.0 - ([7b1d981](https://github.com/dustinblackman/cargo-run-bin/commit/7b1d98199b17aa241f063e47a0ce3b1087968104))
147 | - Fix binary.rs lint - ([8f50248](https://github.com/dustinblackman/cargo-run-bin/commit/8f5024858944f82a9660a8cc49b69ad244e6d6c3))
148 |
149 | ## [1.4.1] - 2023-10-06
150 | [v1.4.0..v1.4.1](https://github.com/dustinblackman/cargo-run-bin/compare/v1.4.0..v1.4.1)
151 |
152 |
153 | ### 📚 Documentation
154 |
155 | - Change changelog format - ([b784580](https://github.com/dustinblackman/cargo-run-bin/commit/b784580ebd613f273527bec147baad6b385b848a))
156 |
157 | ### ⚙️ Miscellaneous Tasks
158 |
159 | - Release cargo-run-bin version 1.4.1 - ([4529a15](https://github.com/dustinblackman/cargo-run-bin/commit/4529a155562985e8a893317664997252eb389947))
160 | - Lint - ([16124e7](https://github.com/dustinblackman/cargo-run-bin/commit/16124e7f64308981c902fca5d8e5c3e42863e086))
161 | - Aliases -> Shims - ([00ca465](https://github.com/dustinblackman/cargo-run-bin/commit/00ca465948bc27afaaf767f263ff3c62e464f003))
162 | - `tauri-mobile` -> `cargo-mobile2` - ([e2130fe](https://github.com/dustinblackman/cargo-run-bin/commit/e2130fe1b0813e153ac49ac78bdbb3d289d64bc2))
163 |
164 | ## [1.4.0] - 2023-10-04
165 | [v1.3.2..v1.4.0](https://github.com/dustinblackman/cargo-run-bin/compare/v1.3.2..v1.4.0)
166 |
167 |
168 | ### ⛰️ Features
169 |
170 | - Support git in package source - ([7151499](https://github.com/dustinblackman/cargo-run-bin/commit/7151499b4b47861f84c63b958af8cd36aa8648a9))
171 |
172 | ### 📚 Documentation
173 |
174 | - Add git - ([a97993c](https://github.com/dustinblackman/cargo-run-bin/commit/a97993c9abb74259084f37857a40c3f6b2dad576))
175 |
176 | ### 🧪 Testing
177 |
178 | - Additional git flows - ([a6144eb](https://github.com/dustinblackman/cargo-run-bin/commit/a6144ebcb9bb38479a78b8caf50afbd27551983d))
179 |
180 | ### ⚙️ Miscellaneous Tasks
181 |
182 | - Release cargo-run-bin version 1.4.0 - ([32f72e8](https://github.com/dustinblackman/cargo-run-bin/commit/32f72e8b600164ae188af332af66954e177f88e7))
183 | - Lint - ([ebba9c4](https://github.com/dustinblackman/cargo-run-bin/commit/ebba9c44f97ab0331f8114b72a99caf60c0d8de4))
184 |
185 | ## [1.3.2] - 2023-09-20
186 | [v1.3.1..v1.3.2](https://github.com/dustinblackman/cargo-run-bin/compare/v1.3.1..v1.3.2)
187 |
188 |
189 | ### 🐛 Bug Fixes
190 |
191 | - Deserailizing default-features - ([3c15340](https://github.com/dustinblackman/cargo-run-bin/commit/3c153408947f3aee7a09d7041c9a1d9fdfe5f3a5))
192 |
193 | ### ⚙️ Miscellaneous Tasks
194 |
195 | - Release cargo-run-bin version 1.3.2 - ([be3cc40](https://github.com/dustinblackman/cargo-run-bin/commit/be3cc4059b7d961819d3c47268f30ee1b87b0ec1))
196 |
197 | ## [1.3.1] - 2023-09-20
198 | [v1.3.0..v1.3.1](https://github.com/dustinblackman/cargo-run-bin/compare/v1.3.0..v1.3.1)
199 |
200 |
201 | ### 🐛 Bug Fixes
202 |
203 | - Duplicate PATH entries - ([0914ff7](https://github.com/dustinblackman/cargo-run-bin/commit/0914ff7ba3316d3b9cddc025febf75df3135a002))
204 |
205 | ### ⚙️ Miscellaneous Tasks
206 |
207 | - Release cargo-run-bin version 1.3.1 - ([83349f9](https://github.com/dustinblackman/cargo-run-bin/commit/83349f99e01d665336d26ff7753ffb2a5a6ffb12))
208 |
209 | ## [1.3.0] - 2023-09-20
210 | [v1.2.0..v1.3.0](https://github.com/dustinblackman/cargo-run-bin/compare/v1.2.0..v1.3.0)
211 |
212 |
213 | ### ⛰️ Features
214 |
215 | - Add cargo-gha to path if it exists - ([c404b48](https://github.com/dustinblackman/cargo-run-bin/commit/c404b480e17e9abf12586dc865111d7546609849))
216 | - Add alias scripts - ([3c6dbac](https://github.com/dustinblackman/cargo-run-bin/commit/3c6dbace4e5f2e1442f7da9805aa5a61e8ba5c9b))
217 | - Add crate features config - ([e7d0f4d](https://github.com/dustinblackman/cargo-run-bin/commit/e7d0f4d9ccff32aeb9a04088d84ce933d85d4885))
218 |
219 | ### ⚙️ Miscellaneous Tasks
220 |
221 | - Release cargo-run-bin version 1.3.0 - ([f044465](https://github.com/dustinblackman/cargo-run-bin/commit/f044465c6df800fd4694334982cffa76a7157ec2))
222 | - Update lockfile - ([c6f752f](https://github.com/dustinblackman/cargo-run-bin/commit/c6f752f24a01077fb260c9561c7b4aeed1972fdf))
223 |
224 | ## [1.2.0] - 2023-08-26
225 | [v1.1.5..v1.2.0](https://github.com/dustinblackman/cargo-run-bin/compare/v1.1.5..v1.2.0)
226 |
227 |
228 | ### ⛰️ Features
229 |
230 | - Add support for Cargo workspaces - ([208b000](https://github.com/dustinblackman/cargo-run-bin/commit/208b000f47ee7666009a066a9f2a5124275ea381))
231 |
232 | ### 🐛 Bug Fixes
233 |
234 | - Nightly setup - ([c50b3a5](https://github.com/dustinblackman/cargo-run-bin/commit/c50b3a520f5f0aee7579f816fc8b89b6309fd5d5))
235 |
236 | ### 📚 Documentation
237 |
238 | - Add commit hashes to changelog - ([28e7c84](https://github.com/dustinblackman/cargo-run-bin/commit/28e7c8488da0972b382cb729ad07e208b3535e81))
239 |
240 | ### ⚙️ Miscellaneous Tasks
241 |
242 | - Release cargo-run-bin version 1.2.0 - ([b600075](https://github.com/dustinblackman/cargo-run-bin/commit/b600075b1af551d509fdf9fcfeeff97d74c5d446))
243 |
244 | ## [1.1.5] - 2023-08-12
245 | [v1.1.4..v1.1.5](https://github.com/dustinblackman/cargo-run-bin/compare/v1.1.4..v1.1.5)
246 |
247 |
248 | ### 🐛 Bug Fixes
249 |
250 | - Help command when using cargo - ([25ace47](https://github.com/dustinblackman/cargo-run-bin/commit/25ace47c61a1c7d4e46d734619917ac8539fa2df))
251 |
252 | ### 📚 Documentation
253 |
254 | - Fix links - ([c40edbf](https://github.com/dustinblackman/cargo-run-bin/commit/c40edbfb888aec37400dd70bc5dc39b60d5e65b8))
255 | - Update parameters table - ([5eae9a9](https://github.com/dustinblackman/cargo-run-bin/commit/5eae9a9968478e7fc1eeae6b14333ef83e8283c7))
256 |
257 | ### 🧪 Testing
258 |
259 | - CLI integration snapshots - ([2524b71](https://github.com/dustinblackman/cargo-run-bin/commit/2524b7111f7cb2ac6cbc31f07143c6702f0844ac))
260 |
261 | ### ⚙️ Miscellaneous Tasks
262 |
263 | - Release cargo-run-bin version 1.1.5 - ([d803d74](https://github.com/dustinblackman/cargo-run-bin/commit/d803d74f79384f6b9707eecc6bc58a156f7d3ba4))
264 | - Update dprint - ([499c1bc](https://github.com/dustinblackman/cargo-run-bin/commit/499c1bccc3e1b5b7cb4a61f6610892c2c9fbb5b6))
265 | - Speed up nightly setup command - ([dd30048](https://github.com/dustinblackman/cargo-run-bin/commit/dd30048696a9e7e013415a0ba8820d6afeb763a7))
266 | - Add release profile - ([e12575c](https://github.com/dustinblackman/cargo-run-bin/commit/e12575ced1d842c29158f17c9826e6fd24517883))
267 | - Upgrade binstall to 1.2.0 - ([f015f5c](https://github.com/dustinblackman/cargo-run-bin/commit/f015f5ca265c7d0ac9af9db364e7e1456355d956))
268 | - Remove unused deps - ([2562b7f](https://github.com/dustinblackman/cargo-run-bin/commit/2562b7f16e7b0bed1c92bc1a83301fae5d1697eb))
269 | - Add commit linting - ([b6b358c](https://github.com/dustinblackman/cargo-run-bin/commit/b6b358cc5781b899d8362ae153564ff9060feda5))
270 | - Add release and changelog scripts - ([6b0e2b0](https://github.com/dustinblackman/cargo-run-bin/commit/6b0e2b0d9b6ce0bd6302ca87f38d592ef22824a4))
271 |
272 | ## [1.1.4] - 2023-08-08
273 | [v1.1.3..v1.1.4](https://github.com/dustinblackman/cargo-run-bin/compare/v1.1.3..v1.1.4)
274 |
275 |
276 | ### ⚙️ Miscellaneous Tasks
277 |
278 | - Release v1.1.4 - ([494d7ac](https://github.com/dustinblackman/cargo-run-bin/commit/494d7acfefc7ac8a3e2124b50fcd3f951fc5d196))
279 | - Drop windows releases - ([d65fb49](https://github.com/dustinblackman/cargo-run-bin/commit/d65fb495283573ee2ecac0c7edba66c9551b6a95))
280 |
281 | ## [1.1.3] - 2023-08-08
282 | [v1.1.2..v1.1.3](https://github.com/dustinblackman/cargo-run-bin/compare/v1.1.2..v1.1.3)
283 |
284 |
285 | ### 🐛 Bug Fixes
286 |
287 | - Release workflow - ([f012617](https://github.com/dustinblackman/cargo-run-bin/commit/f012617a3993c58608bcffe9e2d4b9379bbc25d9))
288 |
289 | ### ⚙️ Miscellaneous Tasks
290 |
291 | - Release v1.1.3 - ([7783dbd](https://github.com/dustinblackman/cargo-run-bin/commit/7783dbd4b9f2460c5900c7e00b65d9ec2ab4e54b))
292 |
293 | ## [1.1.2] - 2023-08-08
294 | [v1.1.1..v1.1.2](https://github.com/dustinblackman/cargo-run-bin/compare/v1.1.1..v1.1.2)
295 |
296 |
297 | ### 🐛 Bug Fixes
298 |
299 | - Release workflow - ([27ce8e0](https://github.com/dustinblackman/cargo-run-bin/commit/27ce8e0f63a4a7181ba780791ac8a206fbbe5d5d))
300 |
301 | ### ⚙️ Miscellaneous Tasks
302 |
303 | - Release v1.1.2 - ([883a75f](https://github.com/dustinblackman/cargo-run-bin/commit/883a75ffad28d62d29c7ab87b7cc8bc186898dea))
304 |
305 | ## [1.1.1] - 2023-08-08
306 | [v1.0.1..v1.1.1](https://github.com/dustinblackman/cargo-run-bin/compare/v1.0.1..v1.1.1)
307 |
308 |
309 | ### ⛰️ Features
310 |
311 | - Add binstall support - ([f702124](https://github.com/dustinblackman/cargo-run-bin/commit/f702124692e23f8c14040cf0935b90c4877ed4ee))
312 |
313 | ### 🐛 Bug Fixes
314 |
315 | - Release command - ([af9715b](https://github.com/dustinblackman/cargo-run-bin/commit/af9715b4f741ede4556a6fecfb8d70a9dbd32a9a))
316 |
317 | ### ⚙️ Miscellaneous Tasks
318 |
319 | - Release v1.1.1 - ([a6ddf14](https://github.com/dustinblackman/cargo-run-bin/commit/a6ddf14394f1c251f55899257931a374466bed76))
320 | - Drop cargo release - ([f87e73c](https://github.com/dustinblackman/cargo-run-bin/commit/f87e73c8a2b6fa68832363b0e28f3c106f5a622b))
321 | - Add artifact releases - ([ced0630](https://github.com/dustinblackman/cargo-run-bin/commit/ced06305199c2a47b3465ba23efeeccfd9dfb722))
322 | - Add cargo-cmd - ([150af5b](https://github.com/dustinblackman/cargo-run-bin/commit/150af5b4e1a75f5ca7b816716dbbcd2be0c66000))
323 | - Add clippy to toolchain - ([aa7161e](https://github.com/dustinblackman/cargo-run-bin/commit/aa7161e0bf3ff522144e318b26746359801b0b07))
324 |
325 | ## [1.0.1] - 2023-08-07
326 | [v1.0.0..v1.0.1](https://github.com/dustinblackman/cargo-run-bin/compare/v1.0.0..v1.0.1)
327 |
328 |
329 | ### 🐛 Bug Fixes
330 |
331 | - Sorting aliases - ([b4ccdd1](https://github.com/dustinblackman/cargo-run-bin/commit/b4ccdd189376506d64d1911de0f17e3c49dda0d0))
332 | - Integration tests with code coverage commands - ([9a940f7](https://github.com/dustinblackman/cargo-run-bin/commit/9a940f7dee59fca6136d4f82a39b141fae95f580))
333 | - Test lcov - ([49ea7c1](https://github.com/dustinblackman/cargo-run-bin/commit/49ea7c10cb3a311dc10dd4bef2f9a76668419378))
334 | - Test scripts exiting - ([1440910](https://github.com/dustinblackman/cargo-run-bin/commit/1440910eadfc638cb6a1da65807a2e24bb7e0a97))
335 | - Lint - ([74b66ad](https://github.com/dustinblackman/cargo-run-bin/commit/74b66ad09d2346e7def0ea7275e16f4bd37bd5e6))
336 |
337 | ## [1.0.0] - 2023-08-07
338 | [..v1.0.0](https://github.com/dustinblackman/cargo-run-bin/compare/..v1.0.0)
339 |
340 |
341 | ### ⛰️ Features
342 |
343 | - Add sync aliases - ([5d7ffed](https://github.com/dustinblackman/cargo-run-bin/commit/5d7ffed87bb9ff7b78ce7a228379a35492e45f11))
344 | - Add build and run functionality - ([9a7218c](https://github.com/dustinblackman/cargo-run-bin/commit/9a7218c20c09797097b518a605c1d2b6c365ec30))
345 | - Rewrite reading cargo.toml - ([12bccba](https://github.com/dustinblackman/cargo-run-bin/commit/12bccbaf5e60f7781f27b6b28fb9c4bd0922acc4))
346 | - Add metadata options for binaries - ([3d176a1](https://github.com/dustinblackman/cargo-run-bin/commit/3d176a170b7b1bec81eb8a06d98706164b218657))
347 |
348 | ### 🐛 Bug Fixes
349 |
350 | - Llvm-cov - ([257af9d](https://github.com/dustinblackman/cargo-run-bin/commit/257af9dc7903eddcf923e0ab55b3575917d0baaf))
351 | - Cargo commands, add initial tests - ([66a2271](https://github.com/dustinblackman/cargo-run-bin/commit/66a2271ca4ea57013d85d36a528c749d057d2959))
352 |
353 | ### 📚 Documentation
354 |
355 | - Format - ([9f1b0db](https://github.com/dustinblackman/cargo-run-bin/commit/9f1b0dbba03293a3f120bfc8f4dcf0eeb1540734))
356 | - Update readme - ([8ab7f77](https://github.com/dustinblackman/cargo-run-bin/commit/8ab7f777fcbd99bb1e50067476ad621b0102013e))
357 |
358 | ### 🧪 Testing
359 |
360 | - Cli integration tests - ([d087a06](https://github.com/dustinblackman/cargo-run-bin/commit/d087a066c3b160240a33c7096e38d3414b8fcaf1))
361 | - Cargo_config - ([281b18b](https://github.com/dustinblackman/cargo-run-bin/commit/281b18b52516c8af89f16e2266c11aa33e321939))
362 | - Binary - ([12146af](https://github.com/dustinblackman/cargo-run-bin/commit/12146afcb515b837a36900afcc3185a0987aec36))
363 | - Bin target packages - ([edf2c1f](https://github.com/dustinblackman/cargo-run-bin/commit/edf2c1f905c28f68244f5af65bdf79e55b233d8f))
364 |
365 | ### ⚙️ Miscellaneous Tasks
366 |
367 | - Add release command - ([b40f043](https://github.com/dustinblackman/cargo-run-bin/commit/b40f0436e8eb231975168fda87fdb8da0f675d0a))
368 | - Update test commands - ([c12a4d6](https://github.com/dustinblackman/cargo-run-bin/commit/c12a4d6c90aed2cc944082dae4f779a5cd8cc5cf))
369 | - Update ci - ([6671333](https://github.com/dustinblackman/cargo-run-bin/commit/6671333b5978890d804b2be71f2d3f2f1299f83e))
370 | - Lint - ([cd157a7](https://github.com/dustinblackman/cargo-run-bin/commit/cd157a727734d06322a4941ff35aa3db6a092670))
371 | - Clean error outputs, unused deps - ([b0171f4](https://github.com/dustinblackman/cargo-run-bin/commit/b0171f4a4d321dae6c783d224ab645ffaa67a555))
372 | - Clean - ([10216bb](https://github.com/dustinblackman/cargo-run-bin/commit/10216bb2399e3d22ef71f6d87954cf207eab1ee0))
373 | - Upgrade cargo_toml - ([b81dcd6](https://github.com/dustinblackman/cargo-run-bin/commit/b81dcd607089b05eb939e915514334b070a4bb35))
374 | - Drop fstrings - ([b5388e3](https://github.com/dustinblackman/cargo-run-bin/commit/b5388e33b000d54444fa5213472546eb3164872d))
375 | - Format - ([cbc9e3a](https://github.com/dustinblackman/cargo-run-bin/commit/cbc9e3ab710c863ef28fcb68583ab4bb07c9dadc))
376 |
377 |
378 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "anstream"
7 | version = "0.3.2"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
10 | dependencies = [
11 | "anstyle",
12 | "anstyle-parse",
13 | "anstyle-query",
14 | "anstyle-wincon",
15 | "colorchoice",
16 | "is-terminal",
17 | "utf8parse",
18 | ]
19 |
20 | [[package]]
21 | name = "anstyle"
22 | version = "1.0.3"
23 | source = "registry+https://github.com/rust-lang/crates.io-index"
24 | checksum = "b84bf0a05bbb2a83e5eb6fa36bb6e87baa08193c35ff52bbf6b38d8af2890e46"
25 |
26 | [[package]]
27 | name = "anstyle-parse"
28 | version = "0.2.1"
29 | source = "registry+https://github.com/rust-lang/crates.io-index"
30 | checksum = "938874ff5980b03a87c5524b3ae5b59cf99b1d6bc836848df7bc5ada9643c333"
31 | dependencies = [
32 | "utf8parse",
33 | ]
34 |
35 | [[package]]
36 | name = "anstyle-query"
37 | version = "1.0.0"
38 | source = "registry+https://github.com/rust-lang/crates.io-index"
39 | checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
40 | dependencies = [
41 | "windows-sys 0.48.0",
42 | ]
43 |
44 | [[package]]
45 | name = "anstyle-wincon"
46 | version = "1.0.2"
47 | source = "registry+https://github.com/rust-lang/crates.io-index"
48 | checksum = "c677ab05e09154296dd37acecd46420c17b9713e8366facafa8fc0885167cf4c"
49 | dependencies = [
50 | "anstyle",
51 | "windows-sys 0.48.0",
52 | ]
53 |
54 | [[package]]
55 | name = "anyhow"
56 | version = "1.0.40"
57 | source = "registry+https://github.com/rust-lang/crates.io-index"
58 | checksum = "28b2cd92db5cbd74e8e5028f7e27dd7aa3090e89e4f2a197cc7c8dfb69c7063b"
59 |
60 | [[package]]
61 | name = "assert_cmd"
62 | version = "2.0.12"
63 | source = "registry+https://github.com/rust-lang/crates.io-index"
64 | checksum = "88903cb14723e4d4003335bb7f8a14f27691649105346a0f0957466c096adfe6"
65 | dependencies = [
66 | "anstyle",
67 | "bstr",
68 | "doc-comment",
69 | "predicates",
70 | "predicates-core",
71 | "predicates-tree",
72 | "wait-timeout",
73 | ]
74 |
75 | [[package]]
76 | name = "bitflags"
77 | version = "2.4.0"
78 | source = "registry+https://github.com/rust-lang/crates.io-index"
79 | checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
80 |
81 | [[package]]
82 | name = "bstr"
83 | version = "1.6.2"
84 | source = "registry+https://github.com/rust-lang/crates.io-index"
85 | checksum = "4c2f7349907b712260e64b0afe2f84692af14a454be26187d9df565c7f69266a"
86 | dependencies = [
87 | "memchr",
88 | "regex-automata",
89 | "serde",
90 | ]
91 |
92 | [[package]]
93 | name = "cargo-bin"
94 | version = "0.0.0"
95 | dependencies = [
96 | "cargo-run-bin 1.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
97 | ]
98 |
99 | [[package]]
100 | name = "cargo-husky"
101 | version = "1.5.0"
102 | source = "registry+https://github.com/rust-lang/crates.io-index"
103 | checksum = "7b02b629252fe8ef6460461409564e2c21d0c8e77e0944f3d189ff06c4e932ad"
104 |
105 | [[package]]
106 | name = "cargo-run-bin"
107 | version = "1.7.4"
108 | dependencies = [
109 | "anyhow",
110 | "assert_cmd",
111 | "cargo-husky",
112 | "cfg-if",
113 | "clap",
114 | "insta",
115 | "rustversion",
116 | "serde",
117 | "toml",
118 | "toml_edit",
119 | "version_check",
120 | "which",
121 | ]
122 |
123 | [[package]]
124 | name = "cargo-run-bin"
125 | version = "1.7.4"
126 | source = "registry+https://github.com/rust-lang/crates.io-index"
127 | checksum = "0770bfdecb25f182aa143e443765b8ecf6f0e6431d8c42ad997b17900c9b6c48"
128 | dependencies = [
129 | "anyhow",
130 | "cfg-if",
131 | "clap",
132 | "rustversion",
133 | "serde",
134 | "toml",
135 | "toml_edit",
136 | "version_check",
137 | "which",
138 | ]
139 |
140 | [[package]]
141 | name = "cfg-if"
142 | version = "1.0.0"
143 | source = "registry+https://github.com/rust-lang/crates.io-index"
144 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
145 |
146 | [[package]]
147 | name = "clap"
148 | version = "4.3.19"
149 | source = "registry+https://github.com/rust-lang/crates.io-index"
150 | checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d"
151 | dependencies = [
152 | "clap_builder",
153 | ]
154 |
155 | [[package]]
156 | name = "clap_builder"
157 | version = "4.3.19"
158 | source = "registry+https://github.com/rust-lang/crates.io-index"
159 | checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1"
160 | dependencies = [
161 | "anstream",
162 | "anstyle",
163 | "clap_lex",
164 | "strsim",
165 | ]
166 |
167 | [[package]]
168 | name = "clap_lex"
169 | version = "0.5.1"
170 | source = "registry+https://github.com/rust-lang/crates.io-index"
171 | checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961"
172 |
173 | [[package]]
174 | name = "colorchoice"
175 | version = "1.0.0"
176 | source = "registry+https://github.com/rust-lang/crates.io-index"
177 | checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
178 |
179 | [[package]]
180 | name = "console"
181 | version = "0.15.7"
182 | source = "registry+https://github.com/rust-lang/crates.io-index"
183 | checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
184 | dependencies = [
185 | "encode_unicode",
186 | "lazy_static",
187 | "libc",
188 | "windows-sys 0.45.0",
189 | ]
190 |
191 | [[package]]
192 | name = "difflib"
193 | version = "0.4.0"
194 | source = "registry+https://github.com/rust-lang/crates.io-index"
195 | checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
196 |
197 | [[package]]
198 | name = "doc-comment"
199 | version = "0.3.3"
200 | source = "registry+https://github.com/rust-lang/crates.io-index"
201 | checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
202 |
203 | [[package]]
204 | name = "either"
205 | version = "1.9.0"
206 | source = "registry+https://github.com/rust-lang/crates.io-index"
207 | checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
208 |
209 | [[package]]
210 | name = "encode_unicode"
211 | version = "0.3.6"
212 | source = "registry+https://github.com/rust-lang/crates.io-index"
213 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
214 |
215 | [[package]]
216 | name = "equivalent"
217 | version = "1.0.1"
218 | source = "registry+https://github.com/rust-lang/crates.io-index"
219 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
220 |
221 | [[package]]
222 | name = "errno"
223 | version = "0.3.8"
224 | source = "registry+https://github.com/rust-lang/crates.io-index"
225 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
226 | dependencies = [
227 | "libc",
228 | "windows-sys 0.52.0",
229 | ]
230 |
231 | [[package]]
232 | name = "hashbrown"
233 | version = "0.14.0"
234 | source = "registry+https://github.com/rust-lang/crates.io-index"
235 | checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
236 |
237 | [[package]]
238 | name = "hermit-abi"
239 | version = "0.3.3"
240 | source = "registry+https://github.com/rust-lang/crates.io-index"
241 | checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7"
242 |
243 | [[package]]
244 | name = "indexmap"
245 | version = "2.0.0"
246 | source = "registry+https://github.com/rust-lang/crates.io-index"
247 | checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
248 | dependencies = [
249 | "equivalent",
250 | "hashbrown",
251 | ]
252 |
253 | [[package]]
254 | name = "insta"
255 | version = "1.31.0"
256 | source = "registry+https://github.com/rust-lang/crates.io-index"
257 | checksum = "a0770b0a3d4c70567f0d58331f3088b0e4c4f56c9b8d764efe654b4a5d46de3a"
258 | dependencies = [
259 | "console",
260 | "lazy_static",
261 | "linked-hash-map",
262 | "serde",
263 | "similar",
264 | "yaml-rust",
265 | ]
266 |
267 | [[package]]
268 | name = "is-terminal"
269 | version = "0.4.9"
270 | source = "registry+https://github.com/rust-lang/crates.io-index"
271 | checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
272 | dependencies = [
273 | "hermit-abi",
274 | "rustix",
275 | "windows-sys 0.48.0",
276 | ]
277 |
278 | [[package]]
279 | name = "itertools"
280 | version = "0.11.0"
281 | source = "registry+https://github.com/rust-lang/crates.io-index"
282 | checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57"
283 | dependencies = [
284 | "either",
285 | ]
286 |
287 | [[package]]
288 | name = "lazy_static"
289 | version = "1.4.0"
290 | source = "registry+https://github.com/rust-lang/crates.io-index"
291 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
292 |
293 | [[package]]
294 | name = "libc"
295 | version = "0.2.151"
296 | source = "registry+https://github.com/rust-lang/crates.io-index"
297 | checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4"
298 |
299 | [[package]]
300 | name = "linked-hash-map"
301 | version = "0.5.6"
302 | source = "registry+https://github.com/rust-lang/crates.io-index"
303 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
304 |
305 | [[package]]
306 | name = "linux-raw-sys"
307 | version = "0.4.12"
308 | source = "registry+https://github.com/rust-lang/crates.io-index"
309 | checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456"
310 |
311 | [[package]]
312 | name = "memchr"
313 | version = "2.6.3"
314 | source = "registry+https://github.com/rust-lang/crates.io-index"
315 | checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
316 |
317 | [[package]]
318 | name = "once_cell"
319 | version = "1.18.0"
320 | source = "registry+https://github.com/rust-lang/crates.io-index"
321 | checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
322 |
323 | [[package]]
324 | name = "predicates"
325 | version = "3.0.4"
326 | source = "registry+https://github.com/rust-lang/crates.io-index"
327 | checksum = "6dfc28575c2e3f19cb3c73b93af36460ae898d426eba6fc15b9bd2a5220758a0"
328 | dependencies = [
329 | "anstyle",
330 | "difflib",
331 | "itertools",
332 | "predicates-core",
333 | ]
334 |
335 | [[package]]
336 | name = "predicates-core"
337 | version = "1.0.6"
338 | source = "registry+https://github.com/rust-lang/crates.io-index"
339 | checksum = "b794032607612e7abeb4db69adb4e33590fa6cf1149e95fd7cb00e634b92f174"
340 |
341 | [[package]]
342 | name = "predicates-tree"
343 | version = "1.0.9"
344 | source = "registry+https://github.com/rust-lang/crates.io-index"
345 | checksum = "368ba315fb8c5052ab692e68a0eefec6ec57b23a36959c14496f0b0df2c0cecf"
346 | dependencies = [
347 | "predicates-core",
348 | "termtree",
349 | ]
350 |
351 | [[package]]
352 | name = "proc-macro2"
353 | version = "1.0.67"
354 | source = "registry+https://github.com/rust-lang/crates.io-index"
355 | checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
356 | dependencies = [
357 | "unicode-ident",
358 | ]
359 |
360 | [[package]]
361 | name = "quote"
362 | version = "1.0.33"
363 | source = "registry+https://github.com/rust-lang/crates.io-index"
364 | checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
365 | dependencies = [
366 | "proc-macro2",
367 | ]
368 |
369 | [[package]]
370 | name = "regex-automata"
371 | version = "0.3.8"
372 | source = "registry+https://github.com/rust-lang/crates.io-index"
373 | checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
374 |
375 | [[package]]
376 | name = "rustix"
377 | version = "0.38.28"
378 | source = "registry+https://github.com/rust-lang/crates.io-index"
379 | checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316"
380 | dependencies = [
381 | "bitflags",
382 | "errno",
383 | "libc",
384 | "linux-raw-sys",
385 | "windows-sys 0.52.0",
386 | ]
387 |
388 | [[package]]
389 | name = "rustversion"
390 | version = "1.0.14"
391 | source = "registry+https://github.com/rust-lang/crates.io-index"
392 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
393 |
394 | [[package]]
395 | name = "serde"
396 | version = "1.0.149"
397 | source = "registry+https://github.com/rust-lang/crates.io-index"
398 | checksum = "256b9932320c590e707b94576e3cc1f7c9024d0ee6612dfbcf1cb106cbe8e055"
399 | dependencies = [
400 | "serde_derive",
401 | ]
402 |
403 | [[package]]
404 | name = "serde_derive"
405 | version = "1.0.149"
406 | source = "registry+https://github.com/rust-lang/crates.io-index"
407 | checksum = "b4eae9b04cbffdfd550eb462ed33bc6a1b68c935127d008b27444d08380f94e4"
408 | dependencies = [
409 | "proc-macro2",
410 | "quote",
411 | "syn",
412 | ]
413 |
414 | [[package]]
415 | name = "similar"
416 | version = "2.2.1"
417 | source = "registry+https://github.com/rust-lang/crates.io-index"
418 | checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
419 |
420 | [[package]]
421 | name = "strsim"
422 | version = "0.10.0"
423 | source = "registry+https://github.com/rust-lang/crates.io-index"
424 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
425 |
426 | [[package]]
427 | name = "syn"
428 | version = "1.0.109"
429 | source = "registry+https://github.com/rust-lang/crates.io-index"
430 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
431 | dependencies = [
432 | "proc-macro2",
433 | "quote",
434 | "unicode-ident",
435 | ]
436 |
437 | [[package]]
438 | name = "termtree"
439 | version = "0.4.1"
440 | source = "registry+https://github.com/rust-lang/crates.io-index"
441 | checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76"
442 |
443 | [[package]]
444 | name = "toml"
445 | version = "0.5.9"
446 | source = "registry+https://github.com/rust-lang/crates.io-index"
447 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7"
448 | dependencies = [
449 | "serde",
450 | ]
451 |
452 | [[package]]
453 | name = "toml_datetime"
454 | version = "0.6.3"
455 | source = "registry+https://github.com/rust-lang/crates.io-index"
456 | checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
457 |
458 | [[package]]
459 | name = "toml_edit"
460 | version = "0.19.14"
461 | source = "registry+https://github.com/rust-lang/crates.io-index"
462 | checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a"
463 | dependencies = [
464 | "indexmap",
465 | "toml_datetime",
466 | "winnow",
467 | ]
468 |
469 | [[package]]
470 | name = "unicode-ident"
471 | version = "1.0.12"
472 | source = "registry+https://github.com/rust-lang/crates.io-index"
473 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
474 |
475 | [[package]]
476 | name = "utf8parse"
477 | version = "0.2.1"
478 | source = "registry+https://github.com/rust-lang/crates.io-index"
479 | checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
480 |
481 | [[package]]
482 | name = "version_check"
483 | version = "0.9.3"
484 | source = "registry+https://github.com/rust-lang/crates.io-index"
485 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
486 |
487 | [[package]]
488 | name = "wait-timeout"
489 | version = "0.2.0"
490 | source = "registry+https://github.com/rust-lang/crates.io-index"
491 | checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
492 | dependencies = [
493 | "libc",
494 | ]
495 |
496 | [[package]]
497 | name = "which"
498 | version = "4.4.0"
499 | source = "registry+https://github.com/rust-lang/crates.io-index"
500 | checksum = "2441c784c52b289a054b7201fc93253e288f094e2f4be9058343127c4226a269"
501 | dependencies = [
502 | "either",
503 | "libc",
504 | "once_cell",
505 | ]
506 |
507 | [[package]]
508 | name = "windows-sys"
509 | version = "0.45.0"
510 | source = "registry+https://github.com/rust-lang/crates.io-index"
511 | checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
512 | dependencies = [
513 | "windows-targets 0.42.2",
514 | ]
515 |
516 | [[package]]
517 | name = "windows-sys"
518 | version = "0.48.0"
519 | source = "registry+https://github.com/rust-lang/crates.io-index"
520 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
521 | dependencies = [
522 | "windows-targets 0.48.5",
523 | ]
524 |
525 | [[package]]
526 | name = "windows-sys"
527 | version = "0.52.0"
528 | source = "registry+https://github.com/rust-lang/crates.io-index"
529 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
530 | dependencies = [
531 | "windows-targets 0.52.0",
532 | ]
533 |
534 | [[package]]
535 | name = "windows-targets"
536 | version = "0.42.2"
537 | source = "registry+https://github.com/rust-lang/crates.io-index"
538 | checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071"
539 | dependencies = [
540 | "windows_aarch64_gnullvm 0.42.2",
541 | "windows_aarch64_msvc 0.42.2",
542 | "windows_i686_gnu 0.42.2",
543 | "windows_i686_msvc 0.42.2",
544 | "windows_x86_64_gnu 0.42.2",
545 | "windows_x86_64_gnullvm 0.42.2",
546 | "windows_x86_64_msvc 0.42.2",
547 | ]
548 |
549 | [[package]]
550 | name = "windows-targets"
551 | version = "0.48.5"
552 | source = "registry+https://github.com/rust-lang/crates.io-index"
553 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
554 | dependencies = [
555 | "windows_aarch64_gnullvm 0.48.5",
556 | "windows_aarch64_msvc 0.48.5",
557 | "windows_i686_gnu 0.48.5",
558 | "windows_i686_msvc 0.48.5",
559 | "windows_x86_64_gnu 0.48.5",
560 | "windows_x86_64_gnullvm 0.48.5",
561 | "windows_x86_64_msvc 0.48.5",
562 | ]
563 |
564 | [[package]]
565 | name = "windows-targets"
566 | version = "0.52.0"
567 | source = "registry+https://github.com/rust-lang/crates.io-index"
568 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
569 | dependencies = [
570 | "windows_aarch64_gnullvm 0.52.0",
571 | "windows_aarch64_msvc 0.52.0",
572 | "windows_i686_gnu 0.52.0",
573 | "windows_i686_msvc 0.52.0",
574 | "windows_x86_64_gnu 0.52.0",
575 | "windows_x86_64_gnullvm 0.52.0",
576 | "windows_x86_64_msvc 0.52.0",
577 | ]
578 |
579 | [[package]]
580 | name = "windows_aarch64_gnullvm"
581 | version = "0.42.2"
582 | source = "registry+https://github.com/rust-lang/crates.io-index"
583 | checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8"
584 |
585 | [[package]]
586 | name = "windows_aarch64_gnullvm"
587 | version = "0.48.5"
588 | source = "registry+https://github.com/rust-lang/crates.io-index"
589 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
590 |
591 | [[package]]
592 | name = "windows_aarch64_gnullvm"
593 | version = "0.52.0"
594 | source = "registry+https://github.com/rust-lang/crates.io-index"
595 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
596 |
597 | [[package]]
598 | name = "windows_aarch64_msvc"
599 | version = "0.42.2"
600 | source = "registry+https://github.com/rust-lang/crates.io-index"
601 | checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43"
602 |
603 | [[package]]
604 | name = "windows_aarch64_msvc"
605 | version = "0.48.5"
606 | source = "registry+https://github.com/rust-lang/crates.io-index"
607 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
608 |
609 | [[package]]
610 | name = "windows_aarch64_msvc"
611 | version = "0.52.0"
612 | source = "registry+https://github.com/rust-lang/crates.io-index"
613 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
614 |
615 | [[package]]
616 | name = "windows_i686_gnu"
617 | version = "0.42.2"
618 | source = "registry+https://github.com/rust-lang/crates.io-index"
619 | checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f"
620 |
621 | [[package]]
622 | name = "windows_i686_gnu"
623 | version = "0.48.5"
624 | source = "registry+https://github.com/rust-lang/crates.io-index"
625 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
626 |
627 | [[package]]
628 | name = "windows_i686_gnu"
629 | version = "0.52.0"
630 | source = "registry+https://github.com/rust-lang/crates.io-index"
631 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
632 |
633 | [[package]]
634 | name = "windows_i686_msvc"
635 | version = "0.42.2"
636 | source = "registry+https://github.com/rust-lang/crates.io-index"
637 | checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060"
638 |
639 | [[package]]
640 | name = "windows_i686_msvc"
641 | version = "0.48.5"
642 | source = "registry+https://github.com/rust-lang/crates.io-index"
643 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
644 |
645 | [[package]]
646 | name = "windows_i686_msvc"
647 | version = "0.52.0"
648 | source = "registry+https://github.com/rust-lang/crates.io-index"
649 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
650 |
651 | [[package]]
652 | name = "windows_x86_64_gnu"
653 | version = "0.42.2"
654 | source = "registry+https://github.com/rust-lang/crates.io-index"
655 | checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36"
656 |
657 | [[package]]
658 | name = "windows_x86_64_gnu"
659 | version = "0.48.5"
660 | source = "registry+https://github.com/rust-lang/crates.io-index"
661 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
662 |
663 | [[package]]
664 | name = "windows_x86_64_gnu"
665 | version = "0.52.0"
666 | source = "registry+https://github.com/rust-lang/crates.io-index"
667 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
668 |
669 | [[package]]
670 | name = "windows_x86_64_gnullvm"
671 | version = "0.42.2"
672 | source = "registry+https://github.com/rust-lang/crates.io-index"
673 | checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3"
674 |
675 | [[package]]
676 | name = "windows_x86_64_gnullvm"
677 | version = "0.48.5"
678 | source = "registry+https://github.com/rust-lang/crates.io-index"
679 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
680 |
681 | [[package]]
682 | name = "windows_x86_64_gnullvm"
683 | version = "0.52.0"
684 | source = "registry+https://github.com/rust-lang/crates.io-index"
685 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
686 |
687 | [[package]]
688 | name = "windows_x86_64_msvc"
689 | version = "0.42.2"
690 | source = "registry+https://github.com/rust-lang/crates.io-index"
691 | checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0"
692 |
693 | [[package]]
694 | name = "windows_x86_64_msvc"
695 | version = "0.48.5"
696 | source = "registry+https://github.com/rust-lang/crates.io-index"
697 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
698 |
699 | [[package]]
700 | name = "windows_x86_64_msvc"
701 | version = "0.52.0"
702 | source = "registry+https://github.com/rust-lang/crates.io-index"
703 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
704 |
705 | [[package]]
706 | name = "winnow"
707 | version = "0.5.15"
708 | source = "registry+https://github.com/rust-lang/crates.io-index"
709 | checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc"
710 | dependencies = [
711 | "memchr",
712 | ]
713 |
714 | [[package]]
715 | name = "yaml-rust"
716 | version = "0.4.5"
717 | source = "registry+https://github.com/rust-lang/crates.io-index"
718 | checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
719 | dependencies = [
720 | "linked-hash-map",
721 | ]
722 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cargo-run-bin"
3 | version = "1.7.4"
4 | authors = ["Dustin Blackman"]
5 | categories = ["command-line-utilities", "development-tools::cargo-plugins"]
6 | edition = "2021"
7 | homepage = "https://github.com/dustinblackman/cargo-run-bin"
8 | keywords = ["dev-experiance", "developer-experiance", "bin", "cache", "cli"]
9 | license = "MIT"
10 | readme = "README.md"
11 | repository = "https://github.com/dustinblackman/cargo-run-bin"
12 | rust-version = "1.70.0"
13 | description = "Build, cache, and run binaries scoped in Cargo.toml rather than installing globally. This acts similarly to npm run and gomodrun, and allows your teams to always be running the same tooling versions."
14 | exclude = [
15 | ".cargo-husky",
16 | "tests/",
17 | "cliff.toml",
18 | "deny.toml",
19 | "rust-toolchain.toml"
20 | ]
21 |
22 | [[bin]]
23 | name = "cargo-bin"
24 | path = "src/main.rs"
25 | required-features = ["cli"]
26 |
27 | [features]
28 | default = ["cli"]
29 | cli = ["dep:clap"]
30 |
31 | [dependencies]
32 | anyhow = "1.0.40"
33 | cfg-if = "1.0.0"
34 | clap = { version = "4.3.19", optional = true }
35 | rustversion = "1.0.14"
36 | serde = { version = "1.0.149", features = ["derive"] }
37 | toml = "0.5.9"
38 | toml_edit = "0.19.14"
39 | version_check = "0.9.3"
40 | which = "4.4.0"
41 |
42 | [dev-dependencies]
43 | assert_cmd = "2.0.12"
44 | cargo-husky = { version = "1.5.0", default-features = false, features = ["user-hooks"] }
45 | insta = { version = "1.31.0", features = ["yaml"] }
46 |
47 | [package.metadata.bin]
48 | cargo-cmd = { version = "0.3.1", locked = true }
49 | cargo-deny = { version = "0.13.5", locked = true }
50 | cargo-gha = { version = "1.0.2", locked = true }
51 | cargo-insta = { version = "1.31.0", locked = true }
52 | cargo-llvm-cov = { version = "0.5.25", locked = true }
53 | cargo-nextest = { version = "0.9.57", locked = true }
54 | cargo-watch = { version = "8.4.0", locked = true }
55 | committed = { version = "1.0.20", locked = true }
56 | git-cliff = { version = "1.3.1", locked = true }
57 | # Just added for testing
58 | dustinblackman-hello-world = { version = "0.2.1", git = "https://github.com/dustinblackman/rust-hello-world", bins = ["hello-world-first", "hello-world-second"] }
59 |
60 | [package.metadata.docs.rs]
61 | all-features = false
62 | features = []
63 |
64 | [package.metadata.gha]
65 | targets = ["aarch64-apple-darwin"]
66 |
67 | [[package.metadata.gha.assets]]
68 | owner_repo = "cli/cli"
69 | tag = "v2.40.1"
70 | binaries = ["gh"]
71 | target_archives = { aarch64-apple-darwin = "gh_{NOVTAG}_macOS_arm64.zip" }
72 |
73 | [profile.dev.package.insta]
74 | opt-level = 3
75 |
76 | [profile.dev.package.similar]
77 | opt-level = 3
78 |
79 | [profile.release]
80 | opt-level = 3
81 | lto = "thin"
82 | strip = "symbols"
83 |
84 | [profile.dist]
85 | inherits = "release"
86 |
87 | [package.metadata.commands]
88 | lint = '''set -e
89 | cargo cmd setup-nightly
90 | cargo +runbin-nightly fmt -- --check
91 | cargo clippy
92 | cargo deny check licenses -s
93 | '''
94 | lint-fix = '''set -e
95 | cargo cmd setup-nightly
96 | cargo clippy --fix --allow-dirty
97 | cargo fix --allow-dirty
98 | cargo +runbin-nightly fmt
99 | '''
100 |
101 | get-nightly-name = 'echo runbin-nightly'
102 | setup-nightly = '''
103 | export NIGHTLY=nightly-2023-06-16
104 | rustup toolchain list -v | grep -q "$NIGHTLY" || rustup toolchain install "$NIGHTLY" --force --component llvm-tools-preview rustfmt
105 | rustup toolchain link runbin-nightly "$(rustup toolchain list -v | grep $NIGHTLY | grep '^nightly-' | awk '{print $2}')"
106 | '''
107 |
108 | release = '''set -e
109 | export RB_VERSION=$(cat Cargo.toml | grep version | head -n1 | awk -F '"' '{print $2}')
110 |
111 | cargo check
112 | cargo bin git-cliff -o CHANGELOG.md --tag "v$RB_VERSION"
113 |
114 | git add .
115 | git commit -m "feat: Release v$RB_VERSION"
116 | git tag -a "v$RB_VERSION" -m "v$RB_VERSION"
117 |
118 | git push
119 | git push --tags
120 |
121 | cargo publish
122 | cargo gha gh release create "v$RB_VERSION" --generate-notes
123 | cargo bin git-cliff --latest --strip header | cargo gha gh release edit "v$RB_VERSION" --notes-file -
124 | '''
125 |
126 | test-coverage = '''set -e
127 | rm -rf .tmp
128 | cargo build
129 | cargo llvm-cov nextest -j 1 --ignore-filename-regex='_test.rs'
130 | '''
131 | test-coverage-html = '''set -e
132 | rm -rf .tmp
133 | cargo build
134 | cargo llvm-cov nextest -j 1 --open --ignore-filename-regex='_test.rs'
135 | '''
136 | test-coverage-lcov = '''set -e
137 | rm -rf .tmp
138 | cargo build
139 | rm -f lcov.info
140 | cargo llvm-cov nextest -j 1 --lcov --output-path lcov.info --ignore-filename-regex='_test.rs'
141 | '''
142 | test = '''set -e
143 | rm -rf .tmp
144 | cargo build
145 | cargo nextest run -j 1
146 | '''
147 | test-watch = '''set -e
148 | cargo watch -i .cargo -x 'cmd test'
149 | '''
150 |
151 | [workspace]
152 | members = ["tools/cargo-bin"]
153 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2021 Dustin Blackman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
cargo-run-bin
2 |
3 | 
4 |
5 | [](https://github.com/dustinblackman/cargo-run-bin/actions)
6 | [](https://coveralls.io/github/dustinblackman/cargo-run-bin?branch=master)
7 | [](https://crates.io/crates/cargo-run-bin)
8 |
9 | > Build, cache, and run CLI tools scoped in `Cargo.toml` rather than installing globally. Stop the version drifts across your team, keep it all in sync within your project!
10 |
11 | - [Overview](#overview)
12 | - [Install](#install)
13 | - [Usage](#usage)
14 | - [cargo bin CRATE](#cargo-bin-crate)
15 | - [cargo bin --sync-aliases](#cargo-bin---sync-aliases)
16 | - [cargo bin --install](#cargo-bin---install)
17 | - [Library](#library)
18 | - [License](#license)
19 |
20 | ## Overview
21 |
22 | Installing tooling globally when working in teams or on CI is a silly problem to manage. `cargo-run-bin` builds, caches, and executes binaries from their locked down versions in `Cargo.toml`. This acts similarly to [`npm run`](https://docs.npmjs.com/cli/v7/commands/npm-run-script) and [`gomodrun`](https://github.com/dustinblackman/gomodrun), and allows your teams to always be running the same tooling versions.
23 |
24 | For command lines that extend cargo such as `cargo-nextest`, run-bin will create and manage cargo aliases to allow using cargo extensions without any changes to your command line scripts! `cargo-run-bin` gets out of your way, and you'll forget you're even using it!
25 |
26 | ## Install
27 |
28 | Minimum Rust Version: 1.70.0
29 |
30 | There are a few different ways you can install `cargo-run-bin`. I'd recommend giving each a read, and picking the best that suits you!
31 |
32 | ### Global Install
33 |
34 | Run the following to install `cargo-run-bin`, and ignore the cache directory in your project.
35 |
36 | ```sh
37 | cargo install cargo-run-bin
38 | cd my/rust/project
39 | echo ".bin/" >> .gitignore
40 | ```
41 |
42 | ### Using wrapper
43 |
44 | Installing with a minimal wrapper and an alias in your project. This gives you the best onboarding experiance in to your project for you and your team as it does not require any global installs! Git pull, and you're ready to consume all your CLI tools!
45 |
46 | These instructions assume you'd like to place the wrapper in `tools/cargo-bin` within your project. Change it to fit your needs!
47 |
48 | ```sh
49 | cd my/rust/project
50 | echo ".bin/" >> .gitignore
51 | cargo new --vcs none --bin tools/cargo-bin
52 | curl --output tools/cargo-bin/src/main.rs https://raw.githubusercontent.com/dustinblackman/cargo-run-bin/refs/tags/v1.7.4/src/main.rs
53 | cd tools/cargo-bin
54 | cargo add --features cli cargo-run-bin
55 | ```
56 |
57 | Ensure the tool binary is added to the workspace within `Cargo.toml`.
58 |
59 | ```toml
60 | [workspace]
61 | members = ["tools/cargo-bin"]
62 | ```
63 |
64 | Now add an alias in `.cargo/config.toml`. If the file doesn't exist yet, then this will be the first entry!
65 |
66 | ```toml
67 | [alias]
68 | bin = ["run", "--package", "cargo-bin", "--"]
69 | ```
70 |
71 | Done! Now it can be used as if installed globally.
72 |
73 | ```sh
74 | cargo bin --version
75 | ```
76 |
77 | ### As a library
78 |
79 | You can also use it as a library within your existing logic.
80 |
81 | ```toml
82 | [dependencies]
83 | cargo-run-bin = { version = "1.7.4", default-features = false }
84 | ```
85 |
86 | ### Distro packages
87 |
88 |
89 | Packaging status
90 |
91 | [](https://repology.org/project/cargo-run-bin/versions)
92 |
93 |
94 |
95 | If your distribution has packaged `cargo-run-bin`, you can use that package for the installation.
96 |
97 | ### Arch Linux
98 |
99 | You can use [pacman](https://wiki.archlinux.org/title/Pacman) to install from the [extra repository](https://archlinux.org/packages/extra/x86_64/cargo-run-bin/):
100 |
101 | ```sh
102 | pacman -S cargo-run-bin
103 | ```
104 |
105 | ### Alpine Linux
106 |
107 | `cargo-run-bin` is available for [Alpine Edge](https://pkgs.alpinelinux.org/packages?name=cargo-run-bin&branch=edge). It can be installed via [apk](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper) after enabling the [testing repository](https://wiki.alpinelinux.org/wiki/Repositories).
108 |
109 | ```sh
110 | apk add cargo-run-bin
111 | ```
112 |
113 | ## Usage
114 |
115 | `cargo-run-bin` keeps track of the binaries and their versions from within `Cargo.toml` under the `[package.metadata.bin]`.
116 | table. A quick example taken from this repo:
117 |
118 | ```toml
119 | [package.metadata.bin]
120 | cargo-binstall = { version = "1.1.2" }
121 | cargo-nextest = { version = "0.9.57", locked = true }
122 | dprint = { version = "0.30.3" }
123 | cargo-mobile2 = { version = "0.5.2", bins = ["cargo-android", "cargo-mobile"], locked = true }
124 | ```
125 |
126 | Or if you're setting up in a workspace:
127 |
128 | ```toml
129 | [workspace.metadata.bin]
130 | cargo-binstall = { version = "1.1.2" }
131 | cargo-nextest = { version = "0.9.57", locked = true }
132 | ```
133 |
134 | | Parameter | Type | Required | Description |
135 | | ---------------- | ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
136 | | version | `String` | true | Specifies the version of the crate. It is not treated as a caret requirement automatically. Corresponds to the `cargo install` [`--version`](https://doc.rust-lang.org/cargo/commands/cargo-install.html#install-options) argument. |
137 | | bins | `Vec` | false | An array of binaries that the crate contains that you wish to build. These can be found in a crates `Cargo.toml` file. See [`cargo-mobile2`](https://github.com/tauri-apps/cargo-mobile2/blob/a5f3783870f48886e3266e43f92a6768fb1eb3d4/Cargo.toml#L18-L28) as an example. |
138 | | locked | `Boolean` | false | A parameter when set to `true` runs `cargo install` with the [`--locked`](https://doc.rust-lang.org/cargo/commands/cargo-install.html#dealing-with-the-lockfile) parameter. |
139 | | features | `Vec` | false | An array of crate features to enable. |
140 | | default-features | `Boolean` | false | When set to `false`, disables all default features. |
141 | | git | String | false | A git URL to install from rather than from crates.io. This will also be used by Binstall to look up Cargo manifist if Binstall is available. |
142 | | branch | String | false | A git branch to install from when `git` is set. This takes priority over `tag` and `rev` |
143 | | tag | String | false | A git tag to install from when `git` is set. `branch` will take priority if set, and takes priority over `rev`. |
144 | | rev | String | false | A git revision to install from when `git` is set. `branch` and `tag` will take priority if set. |
145 | | path | String | false | The path to a local crate to install. |
146 |
147 | If you're a fan of prebuilt binaries and fast downloads, run-bin will use [`cargo-binstall`](https://github.com/cargo-bins/cargo-binstall) if it's installed globally, or configured within `[package.metadata.bin]`, rather than building tools from source.
148 |
149 | ### `cargo bin CRATE`
150 |
151 | Taking an example of `dprint`, running `cargo bin dprint --help` with install/build and cache the dprint binary with the
152 | specified version in `Cargo.toml`. All future executions will run instantly without an install step, and dprint can be used
153 | as you wish!
154 |
155 | ### `cargo bin --sync-aliases`
156 |
157 | With the power of [cargo aliases](https://doc.rust-lang.org/cargo/reference/config.html#alias), `cargo bin --sync-aliases`
158 | will create aliases for any `cargo-*` crate, allowing you to execute commands such `cargo nextest run` that will use
159 | `cargo bin` under the hood. Check out some of the example from [this repo](.cargo/config.toml).
160 |
161 | ### `cargo bin --install`
162 |
163 | When pulling down a new repo, or adding a step to CI, `cargo bin --install` will install or build all binaries that have not been
164 | cached which are configured in `Cargo.toml`.
165 |
166 | ### Library
167 |
168 | `run-bin` can also be used as a library and paired nicely with your `build.rs` or any other scripts. The following
169 | example demos having `dprint` configured within `[package.metadata.bin]`, and executing `dprint --help`.
170 |
171 | ```toml
172 | [package.metadata.bin]
173 | dprint = { version = "0.40.2" }
174 | ```
175 |
176 | ```rust
177 | use anyhow::Result;
178 | use cargo_run_bin::{binary, metadata};
179 |
180 | fn main() -> Result<()> {
181 | let binary_package = metadata::get_binary_packages()?
182 | .iter()
183 | .find(|e| e.package == "dprint")
184 | .unwrap()
185 | .to_owned();
186 | let bin_path = binary::install(binary_package)?;
187 | binary::run(bin_path, vec!["--help".to_string()])?;
188 |
189 | return Ok(());
190 | }
191 | ```
192 |
193 | Using `binary::run` is optional. You can recreate it and make changes to your liking using `std::process`, with shims included!
194 |
195 | ```rust
196 | use std::process;
197 |
198 | use anyhow::Result;
199 | use cargo_run_bin::{binary, metadata, shims};
200 |
201 | fn main() -> Result<()> {
202 | let binary_package = metadata::get_binary_packages()?
203 | .iter()
204 | .find(|e| e.package == "dprint")
205 | .unwrap()
206 | .to_owned();
207 | let bin_path = binary::install(binary_package)?;
208 |
209 | let mut shell_paths = shims::get_shim_paths()?;
210 | shell_paths.push(env::var("PATH").unwrap_or("".to_string()));
211 |
212 | process::Command::new(bin_path)
213 | .args(["--help"])
214 | .env("PATH", shell_paths.join(":"))
215 | .spawn();
216 |
217 | return Ok(());
218 | }
219 | ```
220 |
221 | ## [License](./LICENSE)
222 |
223 | MIT.
224 |
--------------------------------------------------------------------------------
/cliff.toml:
--------------------------------------------------------------------------------
1 | # git-cliff ~ configuration file
2 | # https://git-cliff.org/docs/configuration
3 | #
4 | # Lines starting with "#" are comments.
5 | # Configuration options are organized into tables and keys.
6 | # See documentation for more information on available options.
7 |
8 | [changelog]
9 | # changelog header
10 | header = """
11 | # Changelog\n
12 | All notable changes to this project will be documented in this file.\n
13 | """
14 | # template for the changelog body
15 | # https://keats.github.io/tera/docs/#introduction
16 | body = """
17 | {% if version %}\
18 | ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
19 | {% else %}\
20 | ## [unreleased]
21 | {% endif %}\
22 |
23 | [{{ previous.version }}..{{ version }}](/compare/{{ previous.version }}..{{ version }})
24 |
25 | {% macro commit(commit) -%}
26 | - {% if commit.scope %}*({{ commit.scope }})* {% endif %}{% if commit.breaking %}[**breaking**] {% endif %}\
27 | {{ commit.message | upper_first }} - ([{{ commit.id | truncate(length=7, end="") }}](/commit/{{ commit.id }}))\
28 | {% endmacro -%}
29 |
30 | {% for group, commits in commits | group_by(attribute="group") %}
31 | ### {{ group | striptags | trim | upper_first }}
32 | {% for commit in commits
33 | | filter(attribute="scope")
34 | | sort(attribute="scope") %}
35 | {{ self::commit(commit=commit) }}
36 | {%- endfor -%}
37 | {% raw %}\n{% endraw %}\
38 | {%- for commit in commits %}
39 | {%- if not commit.scope -%}
40 | {{ self::commit(commit=commit) }}
41 | {% endif -%}
42 | {% endfor -%}
43 | {% endfor %}\n
44 | """
45 | # remove the leading and trailing whitespace from the template
46 | trim = true
47 | # changelog footer
48 | footer = """
49 |
50 | """
51 | # postprocessors
52 | postprocessors = [
53 | { pattern = '', replace = "https://github.com/dustinblackman/cargo-run-bin" }, # replace repository URL
54 | ]
55 |
56 | [git]
57 | # parse the commits based on https://www.conventionalcommits.org
58 | conventional_commits = true
59 | # filter out the commits that are not conventional
60 | filter_unconventional = true
61 | # process each line of a commit as an individual commit
62 | split_commits = false
63 | # regex for preprocessing the commit messages
64 | commit_preprocessors = [
65 | { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](/issues/${2}))" },
66 | ]
67 | # regex for parsing and grouping commits
68 | commit_parsers = [
69 | { message = "^feat", group = "⛰️ Features" },
70 | { message = "^fix", group = "🐛 Bug Fixes" },
71 | { message = "^doc", group = "📚 Documentation" },
72 | { message = "^perf", group = "⚡ Performance" },
73 | { message = "^refactor", group = "🚜 Refactor" },
74 | { message = "^style", group = "🎨 Styling" },
75 | { message = "^test", group = "🧪 Testing" },
76 | { message = "^chore\\(release\\): prepare for", skip = true },
77 | { message = "^chore\\(deps\\)", skip = true },
78 | { message = "^chore\\(pr\\)", skip = true },
79 | { message = "^chore\\(pull\\)", skip = true },
80 | { message = "^chore|ci", group = "⚙️ Miscellaneous Tasks" },
81 | { body = ".*security", group = "🛡️ Security" },
82 | { message = "^revert", group = "◀️ Revert" },
83 | ]
84 | # protect breaking changes from being skipped due to matching a skipping commit_parser
85 | protect_breaking_commits = false
86 | # filter out the commits that are not matched by commit parsers
87 | filter_commits = false
88 | # glob pattern for matching git tags
89 | tag_pattern = "v[0-9]*"
90 | # regex for skipping tags
91 | skip_tags = "beta|alpha"
92 | # regex for ignoring tags
93 | ignore_tags = "rc"
94 | # sort the tags topologically
95 | topo_order = false
96 | # sort the commits inside sections by oldest/newest order
97 | sort_commits = "newest"
98 |
--------------------------------------------------------------------------------
/committed.toml:
--------------------------------------------------------------------------------
1 | style = "conventional"
2 | ignore_author_re = "(dependabot)"
3 | merge_commit = false
4 |
--------------------------------------------------------------------------------
/deny.toml:
--------------------------------------------------------------------------------
1 | [advisories]
2 | git-fetch-with-cli = true
3 |
4 | [licenses]
5 | unlicensed = "deny"
6 | copyleft = "deny"
7 | allow = [
8 | "MIT",
9 | "Apache-2.0",
10 | ]
11 | exceptions = [
12 | { allow = ["Unicode-DFS-2016"], name = "unicode-ident" },
13 | ]
14 |
15 | [[licenses.clarify]]
16 | name = "ring"
17 | expression = "MIT AND ISC AND OpenSSL"
18 | license-files = [
19 | { path = "LICENSE", hash = 0xbd0eed23 },
20 | ]
21 |
--------------------------------------------------------------------------------
/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | channel = "1.75.0"
3 | components = ["rustfmt", "clippy", "llvm-tools-preview"]
4 |
--------------------------------------------------------------------------------
/src/binary.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 | use std::fs;
3 | use std::io;
4 | use std::path;
5 | use std::process;
6 |
7 | use anyhow::anyhow;
8 | use anyhow::bail;
9 | use anyhow::Result;
10 | use cfg_if::cfg_if;
11 | use version_check as rustc;
12 | use which::which;
13 |
14 | use crate::cargo_config;
15 | use crate::metadata;
16 | use crate::shims;
17 |
18 | #[rustversion::since(1.74)]
19 | fn stderr_to_stdio() -> io::Result {
20 | return Ok(io::stderr().into());
21 | }
22 |
23 | #[rustversion::before(1.74)]
24 | #[cfg(target_family = "unix")]
25 | fn stderr_to_stdio() -> io::Result {
26 | use std::os::fd::AsFd;
27 |
28 | return Ok(io::stderr().as_fd().try_clone_to_owned()?.into());
29 | }
30 |
31 | #[rustversion::before(1.74)]
32 | #[cfg(target_family = "windows")]
33 | fn stderr_to_stdio() -> io::Result {
34 | use std::os::windows::io::AsHandle;
35 |
36 | return Ok(io::stderr().as_handle().try_clone_to_owned()?.into());
37 | }
38 |
39 | /// INTERNAL: Install binary with cargo install.
40 | pub fn cargo_install(
41 | binary_package: metadata::BinaryPackage,
42 | cache_path: path::PathBuf,
43 | ) -> Result<()> {
44 | let mut cmd_prefix = process::Command::new("cargo");
45 |
46 | cmd_prefix
47 | .stdout(stderr_to_stdio()?)
48 | .stderr(process::Stdio::inherit())
49 | .arg("install")
50 | .arg("--root")
51 | .arg(&cache_path)
52 | .arg("--version")
53 | .arg(binary_package.version);
54 |
55 | if let Some(git) = &binary_package.git {
56 | cmd_prefix.arg("--git").arg(git);
57 | if let Some(branch) = &binary_package.branch {
58 | cmd_prefix.arg("--branch").arg(branch);
59 | } else if let Some(tag) = &binary_package.tag {
60 | cmd_prefix.arg("--tag").arg(tag);
61 | } else if let Some(rev) = &binary_package.rev {
62 | cmd_prefix.arg("--rev").arg(rev);
63 | }
64 | } else if let Some(path) = &binary_package.path {
65 | cmd_prefix.arg("--path").arg(path);
66 | }
67 |
68 | if let Some(bin_target) = &binary_package.bin_target {
69 | cmd_prefix.arg("--bin").arg(bin_target);
70 | }
71 |
72 | if let Some(locked) = &binary_package.locked {
73 | if *locked {
74 | cmd_prefix.arg("--locked");
75 | }
76 | }
77 |
78 | if let Some(features) = &binary_package.features {
79 | cmd_prefix.arg("--features");
80 | cmd_prefix.arg(features.join(","));
81 | }
82 |
83 | if let Some(default_features) = &binary_package.default_features {
84 | if !*default_features {
85 | cmd_prefix.arg("--no-default-features");
86 | }
87 | }
88 |
89 | cmd_prefix.arg(binary_package.package).output()?;
90 |
91 | return Ok(());
92 | }
93 |
94 | /// INTERNAL: Install binary with binstall
95 | pub fn binstall(binary_package: metadata::BinaryPackage, cache_path: path::PathBuf) -> Result<()> {
96 | let mut cmd_prefix = process::Command::new("cargo");
97 |
98 | cmd_prefix
99 | .stdout(stderr_to_stdio()?)
100 | .stderr(process::Stdio::inherit())
101 | .arg("binstall")
102 | .arg("--no-confirm")
103 | .arg("--no-symlinks")
104 | .arg("--root")
105 | .arg(&cache_path)
106 | .arg("--install-path")
107 | .arg(cache_path.join("bin"));
108 |
109 | if let Some(git) = &binary_package.git {
110 | cmd_prefix.arg("--git").arg(git);
111 | }
112 |
113 | if let Some(locked) = &binary_package.locked {
114 | if *locked {
115 | cmd_prefix.arg("--locked");
116 | }
117 | }
118 |
119 | cmd_prefix
120 | .arg(format!(
121 | "{package}@{version}",
122 | package = binary_package.package,
123 | version = binary_package.version,
124 | ))
125 | .output()?;
126 |
127 | return Ok(());
128 | }
129 |
130 | /// Install the provided binary package if it has not been built already.
131 | pub fn install(binary_package: metadata::BinaryPackage) -> Result {
132 | let mut rust_version = "unknown".to_string();
133 | if let Some(res) = rustc::triple() {
134 | if res.1.is_nightly() {
135 | rust_version = "nightly".to_string();
136 | } else {
137 | rust_version = res.0.to_string();
138 | }
139 | }
140 |
141 | let mut bin_name = binary_package.package.to_owned();
142 | if let Some(bin_target) = &binary_package.bin_target {
143 | bin_name = bin_target.to_string();
144 | }
145 |
146 | let cache_path = metadata::get_project_root()?
147 | .join(".bin")
148 | .join(format!("rust-{rust_version}"))
149 | .join(binary_package.package.clone())
150 | .join(binary_package.version.clone());
151 |
152 | let mut cache_bin_path = cache_path.join("bin").join(bin_name);
153 | cache_bin_path = cache_bin_path.clone();
154 |
155 | cfg_if! {
156 | if #[cfg(not(target_family = "unix"))] {
157 | cache_bin_path.set_extension("exe");
158 | }
159 | }
160 |
161 | if !path::Path::new(&cache_bin_path).exists() {
162 | fs::create_dir_all(&cache_path)?;
163 | if binary_package.bin_target.is_none()
164 | && binary_package.features.is_none()
165 | && binary_package.default_features.is_none()
166 | && binary_package.branch.is_none()
167 | && binary_package.tag.is_none()
168 | && binary_package.rev.is_none()
169 | && binary_package.package != "cargo-binstall"
170 | && (cargo_config::binstall_alias_exists()? || which("cargo-binstall").is_ok())
171 | {
172 | binstall(binary_package, cache_path)?;
173 | } else {
174 | cargo_install(binary_package, cache_path)?;
175 | }
176 | }
177 |
178 | return Ok(cache_bin_path.to_str().unwrap().to_string());
179 | }
180 |
181 | /// Executes provided binary and arguments, adding shims to PATH so any
182 | /// other run-bin configured binaries are available.
183 | pub fn run(bin_path: String, args: Vec) -> Result<()> {
184 | // Silly hack to make cargo commands parse arguments correctly.
185 | let mut final_args = args.clone();
186 | let bin_name = path::Path::new(&bin_path)
187 | .file_name()
188 | .unwrap()
189 | .to_str()
190 | .unwrap();
191 | if bin_name.starts_with("cargo-") {
192 | final_args = vec![bin_name
193 | .to_string()
194 | .replace("cargo-", "")
195 | .replace(".exe", "")];
196 | final_args.append(&mut args.clone());
197 | }
198 |
199 | let mut shell_paths = shims::get_shim_paths()?;
200 | shell_paths.push(env::var("PATH").unwrap_or("".to_string()));
201 |
202 | let spawn = process::Command::new(bin_path.clone())
203 | .stdout(process::Stdio::inherit())
204 | .stderr(process::Stdio::inherit())
205 | .stdin(process::Stdio::inherit())
206 | .args(&final_args)
207 | .env("PATH", shell_paths.join(":"))
208 | .spawn();
209 |
210 | if let Ok(mut spawn) = spawn {
211 | let status = spawn
212 | .wait()?
213 | .code()
214 | .ok_or_else(|| return anyhow!("Failed to get spawn exit code"))?;
215 |
216 | process::exit(status);
217 | }
218 |
219 | bail!(format!("Process failed to start: {bin_path}"));
220 | }
221 |
--------------------------------------------------------------------------------
/src/cargo_config.rs:
--------------------------------------------------------------------------------
1 | use std::fs;
2 |
3 | use anyhow::bail;
4 | use anyhow::Context;
5 | use anyhow::Result;
6 | use toml_edit::table;
7 | use toml_edit::value;
8 | use toml_edit::Array;
9 | use toml_edit::Document;
10 | use toml_edit::Value;
11 |
12 | use crate::metadata;
13 |
14 | /// Updates alias' in .cargo/config.toml with all configured cargo extensions.
15 | pub fn sync_aliases() -> Result<()> {
16 | let mut toml_str = "".to_string();
17 | let config_path = metadata::get_project_root()?.join(".cargo/config.toml");
18 | if config_path.exists() {
19 | toml_str = fs::read_to_string(&config_path)?.parse()?;
20 | }
21 |
22 | let binary_packages = metadata::get_binary_packages()?;
23 | let new_config = update_aliases_toml(&toml_str, binary_packages)
24 | .context("failed to update aliases in .cargo/config.toml")?;
25 |
26 | if !config_path.parent().unwrap().exists() {
27 | fs::create_dir(config_path.parent().unwrap())?;
28 | }
29 |
30 | fs::write(config_path, new_config)?;
31 |
32 | return Ok(());
33 | }
34 |
35 | fn update_aliases_toml(
36 | toml_str: &str,
37 | binary_packages: Vec,
38 | ) -> Result {
39 | let mut doc = toml_str.parse::()?;
40 | if doc.get("alias").is_none() {
41 | doc["alias"] = table();
42 | }
43 |
44 | // If the TOML structure is not as and we panic because of that, that makes for
45 | // poor user experience, so try to report errors for everything that could
46 | // go wrong.
47 | let aliases = doc["alias"]
48 | .as_table_mut()
49 | .context("alias key should be a table")?;
50 | let mut remove_keys: Vec = vec![];
51 | for (key, value) in aliases.get_values() {
52 | let [name] = key.as_slice() else {
53 | bail!("unexpected nested table: {key:?}")
54 | };
55 | // The value can be either a single string (implicitly split on spaces) or an
56 | // array of strings. We always create an array, but a user might use a
57 | // single string for other aliases, so we have to at least not crash on
58 | // such values.
59 | if let Value::Array(parts) = value {
60 | let first_part = parts
61 | .get(0)
62 | .with_context(|| format!("alias {name:?} is empty array"))?
63 | .as_str()
64 | .with_context(|| format!("alias {name:?} should be array of strings"))?;
65 | if first_part == "bin" {
66 | remove_keys.push(name.get().to_owned());
67 | }
68 | }
69 | }
70 | for key in remove_keys {
71 | aliases.remove(&key);
72 | }
73 |
74 | for binary_package in binary_packages {
75 | let mut bin = binary_package.package;
76 | if let Some(bin_target) = binary_package.bin_target {
77 | bin = bin_target;
78 | }
79 |
80 | if !bin.starts_with("cargo-") {
81 | continue;
82 | }
83 |
84 | let mut arr = Array::new();
85 | arr.push("bin");
86 | arr.push(bin.clone());
87 | doc["alias"][bin.replace("cargo-", "")] = value(arr);
88 | }
89 | return Ok(doc.to_string());
90 | }
91 |
92 | /// Verifies in cargo-binstall is available in alias'.
93 | pub fn binstall_alias_exists() -> Result {
94 | let config_path = metadata::get_project_root()?.join(".cargo/config.toml");
95 | if !config_path.exists() {
96 | return Ok(false);
97 | }
98 |
99 | let toml_str: String = fs::read_to_string(&config_path)?.parse()?;
100 | let mut doc = toml_str.parse::()?;
101 | if doc.get("alias").is_none() {
102 | return Ok(false);
103 | }
104 |
105 | let aliases = doc["alias"].as_table_mut().unwrap();
106 | return Ok(aliases.contains_key("binstall"));
107 | }
108 |
109 | #[cfg(test)]
110 | mod tests {
111 | use super::update_aliases_toml;
112 |
113 | #[test]
114 | fn skips_bare_string_alias() {
115 | let original_toml = r#"
116 | [alias]
117 | xtask = "run --package xtask --"
118 | "#;
119 | let new_toml = update_aliases_toml(original_toml, Vec::new()).unwrap();
120 | assert_eq!(original_toml, new_toml);
121 | }
122 |
123 | #[test]
124 | fn doesnt_panic_on_empty_array() {
125 | let result = update_aliases_toml("alias.mistake = []", Vec::new());
126 | // Currently an error, could be skipped instead, in that case the Ok(..) result
127 | // should be tested a bit.
128 | assert!(result.is_err());
129 | }
130 |
131 | #[test]
132 | fn doesnt_panic_on_nested_keys() {
133 | let result = update_aliases_toml("alias.alias.alias = 'test'", Vec::new());
134 | // Currently an error, could be skipped instead, in that case the Ok(..) result
135 | // should be tested a bit.
136 | assert!(result.is_err());
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/src/cli.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 |
3 | use anyhow::bail;
4 | use anyhow::Result;
5 | use clap::Arg;
6 | use clap::ArgMatches;
7 | use clap::Command;
8 |
9 | use crate::binary;
10 | use crate::cargo_config;
11 | use crate::metadata;
12 | use crate::shims;
13 |
14 | fn install_all_binaries() -> Result<()> {
15 | let binary_packages = metadata::get_binary_packages()?;
16 | for binary_package in binary_packages {
17 | binary::install(binary_package)?;
18 | }
19 |
20 | println!("\x1b[32mDone!\x1b[0m");
21 | return Ok(());
22 | }
23 |
24 | fn sync_aliases() -> Result<()> {
25 | cargo_config::sync_aliases()?;
26 | println!("\x1b[32mDone!\x1b[0m");
27 | return Ok(());
28 | }
29 |
30 | fn run_binary(binary_name: String, args: Vec) -> Result<()> {
31 | let binary_packages = metadata::get_binary_packages()?;
32 | let binary_package = binary_packages.iter().find(|&e| {
33 | return e.package == binary_name
34 | || (e.bin_target.is_some() && e.bin_target.as_deref().unwrap() == binary_name);
35 | });
36 | if binary_package.is_none() {
37 | bail!(format!("No package found for binary {binary_name}"));
38 | }
39 |
40 | let bin_path = binary::install(binary_package.unwrap().clone())?;
41 | shims::sync()?;
42 | binary::run(bin_path, args)?;
43 |
44 | return Ok(());
45 | }
46 |
47 | fn arg_used(matches: &ArgMatches, arg_long: &str) -> bool {
48 | if let Some(used) = matches.get_one::(arg_long) {
49 | if *used {
50 | return true;
51 | }
52 | }
53 |
54 | if let Some(sub) = matches.subcommand_matches("bin") {
55 | if let Some(used) = sub.get_one::(arg_long) {
56 | if *used {
57 | return true;
58 | }
59 | }
60 | }
61 |
62 | return false;
63 | }
64 |
65 | pub fn run() -> Result<()> {
66 | let arg_sync_aliases = Arg::new("sync-aliases")
67 | .short('s')
68 | .long("sync-aliases")
69 | .num_args(0)
70 | .help("Sync aliases for cargo-* commands in .cargo/config.toml");
71 |
72 | let arg_install = Arg::new("install")
73 | .short('i')
74 | .long("install")
75 | .num_args(0)
76 | .help("Install/build all configured binaries, skips entries that are already installed.");
77 |
78 | let arg_help = Arg::new("help")
79 | .short('h')
80 | .long("help")
81 | .num_args(0)
82 | .help("Print help");
83 |
84 | let arg_version = Arg::new("version")
85 | .short('V')
86 | .long("version")
87 | .num_args(0)
88 | .help("Print version");
89 |
90 | // @deprecated: Use --install.
91 | let arg_build = Arg::new("build")
92 | .short('b')
93 | .long("build")
94 | .hide(true)
95 | .num_args(0);
96 |
97 | let mut app = Command::new("cargo-bin")
98 | .about(env!("CARGO_PKG_DESCRIPTION"))
99 | .author(env!("CARGO_PKG_AUTHORS"))
100 | .version(env!("CARGO_PKG_VERSION"))
101 | .arg_required_else_help(false)
102 | .ignore_errors(true)
103 | .disable_version_flag(true)
104 | .arg(arg_sync_aliases.clone())
105 | .arg(arg_install.clone())
106 | .arg(arg_build.clone())
107 | .arg(arg_version.clone())
108 | .subcommand(
109 | Command::new("bin")
110 | .hide(true)
111 | .disable_help_flag(true)
112 | .arg(arg_sync_aliases)
113 | .arg(arg_install)
114 | .arg(arg_build)
115 | .arg(arg_help)
116 | .arg(arg_version),
117 | );
118 |
119 | let matches = app.clone().get_matches();
120 |
121 | if arg_used(&matches, "sync-aliases") {
122 | sync_aliases()?;
123 | } else if arg_used(&matches, "install") || arg_used(&matches, "build") {
124 | install_all_binaries()?;
125 | } else if arg_used(&matches, "help") {
126 | app.print_long_help()?;
127 | } else if arg_used(&matches, "version") {
128 | println!("cargo-run-bin {}", env!("CARGO_PKG_VERSION"));
129 | } else {
130 | let mut args: Vec<_> = env::args().collect();
131 | let start_index = args
132 | .iter()
133 | .position(|e| return e.ends_with("/cargo-bin") || e.ends_with("cargo-bin.exe"));
134 | if start_index.is_none() || start_index.unwrap() == (args.len() + 1) {
135 | app.print_long_help()?;
136 | return Ok(());
137 | }
138 |
139 | let mut bin_index = start_index.unwrap() + 1;
140 | if args[bin_index] == "bin" {
141 | bin_index += 1;
142 | }
143 | if bin_index >= args.len() {
144 | app.print_long_help()?;
145 | return Ok(());
146 | }
147 |
148 | let binary_name = args[bin_index].clone();
149 | args.drain(0..(bin_index + 1));
150 |
151 | run_binary(binary_name, args)?;
152 | }
153 |
154 | return Ok(());
155 | }
156 |
--------------------------------------------------------------------------------
/src/lib.rs:
--------------------------------------------------------------------------------
1 | //! Installing tooling globally when working in teams or on CI is a silly
2 | //! problem to manage. `cargo-run-bin` builds, caches, and executes binaries
3 | //! from their locked down versions in `Cargo.toml`, and allows your teams to
4 | //! always be running the same tooling versions.
5 | //!
6 | //! For command lines that extend cargo such as `cargo-nextest`, run-bin will
7 | //! create and manage cargo aliases to allow using cargo extensions without any
8 | //! changes to your command line scripts! `cargo-run-bin` gets out of your way,
9 | //! and you'll forget you're even using it!
10 | //!
11 | //! ## Usage
12 | //!
13 | //! For command line usage, see the [GitHub repo](https://github.com/dustinblackman/cargo-run-bin).
14 | //!
15 | //! `run-bin` can also be used as a library and paired nicely with your
16 | //! `build.rs` or any other scripts. The following example demos having `dprint`
17 | //! configured within `[package.metadata.bin]`, and executing `dprint --help`.
18 | //!
19 | //! ```toml
20 | //! [package.metadata.bin]
21 | //! dprint = { version = "0.40.2" }
22 | //! ```
23 | //!
24 | //! ```rust
25 | //! use anyhow::Result;
26 | //! use cargo_run_bin::{binary, metadata};
27 | //!
28 | //! fn main() -> Result<()> {
29 | //! let binary_package = metadata::get_binary_packages()?
30 | //! .iter()
31 | //! .find(|e| e.package == "dprint")
32 | //! .unwrap()
33 | //! .to_owned();
34 | //! let bin_path = binary::install(binary_package)?;
35 | //! binary::run(bin_path, vec!["--help".to_string()])?;
36 | //!
37 | //! return Ok(());
38 | //! }
39 | //! ```
40 | //!
41 | //! Using `binary::run` is optional. You can recreate it and make changes to
42 | //! your liking using `std::process`, with shims included!
43 | //!
44 | //! ```rust
45 | //! use std::process;
46 | //!
47 | //! use anyhow::Result;
48 | //! use cargo_run_bin::{binary, metadata, shims};
49 | //!
50 | //! fn main() -> Result<()> {
51 | //! let binary_package = metadata::get_binary_packages()?
52 | //! .iter()
53 | //! .find(|e| e.package == "dprint")
54 | //! .unwrap()
55 | //! .to_owned();
56 | //! let bin_path = binary::install(binary_package)?;
57 | //!
58 | //! let mut shell_paths = shims::get_shim_paths()?;
59 | //! shell_paths.push(env::var("PATH").unwrap_or("".to_string()));
60 | //!
61 | //! process::Command::new(bin_path)
62 | //! .args(["--help"])
63 | //! .env("PATH", shell_paths.join(":"))
64 | //! .spawn();
65 | //!
66 | //! return Ok(());
67 | //! }
68 | //! ```
69 |
70 | #![deny(clippy::implicit_return)]
71 | #![allow(clippy::needless_return)]
72 |
73 | pub mod binary;
74 | pub mod cargo_config;
75 | #[cfg(not(doc))]
76 | #[cfg(feature = "cli")]
77 | pub mod cli;
78 | pub mod metadata;
79 | pub mod shims;
80 |
--------------------------------------------------------------------------------
/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::process;
2 |
3 | fn main() {
4 | let res = cargo_run_bin::cli::run();
5 |
6 | // Only reached if run-bin code fails, otherwise process exits early from within
7 | // binary::run.
8 | if let Err(res) = res {
9 | eprintln!("\x1b[31m{}\x1b[0m", format!("run-bin failed: {res}"));
10 | process::exit(1);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/metadata.rs:
--------------------------------------------------------------------------------
1 | use std::collections::HashMap;
2 | use std::env;
3 | use std::fs;
4 | use std::path::PathBuf;
5 |
6 | use anyhow::anyhow;
7 | use anyhow::bail;
8 | use anyhow::Result;
9 | use serde::Deserialize;
10 | use toml_edit::Document;
11 | use toml_edit::Item;
12 |
13 | #[cfg(test)]
14 | #[path = "metadata_test.rs"]
15 | mod metadata_test;
16 |
17 | #[derive(Deserialize, Debug, PartialEq)]
18 | struct MetadataValue {
19 | version: String,
20 | git: Option,
21 | branch: Option,
22 | tag: Option,
23 | rev: Option,
24 | path: Option,
25 | locked: Option,
26 | bins: Option>,
27 | #[serde(alias = "default-features")]
28 | default_features: Option,
29 | features: Option>,
30 | }
31 |
32 | type MetadataBins = HashMap;
33 |
34 | #[derive(Clone)]
35 | pub struct BinaryPackage {
36 | pub bin_target: Option,
37 | pub package: String,
38 | pub locked: Option,
39 | pub version: String,
40 | pub git: Option,
41 | pub branch: Option,
42 | pub tag: Option,
43 | pub rev: Option,
44 | pub path: Option,
45 | pub default_features: Option,
46 | pub features: Option>,
47 | }
48 |
49 | pub fn get_project_root() -> Result {
50 | let path = env::current_dir()?;
51 | let path_ancestors = path.as_path().ancestors();
52 |
53 | for p in path_ancestors {
54 | let has_cargo = fs::read_dir(p)?.any(|p| return p.unwrap().file_name() == *"Cargo.lock");
55 |
56 | if has_cargo {
57 | return Ok(PathBuf::from(p));
58 | }
59 | }
60 |
61 | return Err(anyhow!("Root directory for rust project not found."));
62 | }
63 |
64 | fn toml_has_path(doc: &Item, keys: Vec<&str>) -> bool {
65 | let mut item = doc;
66 | for key in keys {
67 | if item.get(key).is_none() {
68 | return false;
69 | }
70 | item = &item[key];
71 | }
72 |
73 | return true;
74 | }
75 |
76 | fn get_metadata_binaries() -> Result {
77 | let toml_str: String = fs::read_to_string(get_project_root()?.join("Cargo.toml"))?.parse()?;
78 | let doc = toml_str.parse::()?;
79 |
80 | let mut metadata_str = "".to_string();
81 | if toml_has_path(doc.as_item(), vec!["package", "metadata", "bin"]) {
82 | metadata_str = doc["package"]["metadata"]["bin"].to_string();
83 | } else if toml_has_path(doc.as_item(), vec!["workspace", "metadata", "bin"]) {
84 | metadata_str = doc["workspace"]["metadata"]["bin"].to_string();
85 | }
86 |
87 | if metadata_str.is_empty() {
88 | bail!("No binaries configured in Cargo.toml");
89 | }
90 |
91 | let metadata_res: Result = toml::from_str(&metadata_str);
92 | return Ok(metadata_res?);
93 | }
94 |
95 | /// Returns all configured binary packages set in Cargo.toml.
96 | pub fn get_binary_packages() -> Result> {
97 | let metadata = get_metadata_binaries()?;
98 |
99 | let mut binary_details: Vec = Vec::new();
100 |
101 | for (pkg_name, pkg_details) in metadata.into_iter() {
102 | if let Some(pkg_bins) = pkg_details.bins {
103 | for bin_target in pkg_bins.iter() {
104 | binary_details.push(BinaryPackage {
105 | bin_target: Some(bin_target.to_string()),
106 | package: pkg_name.clone(),
107 | locked: pkg_details.locked,
108 | version: pkg_details.version.clone(),
109 | git: pkg_details.git.clone(),
110 | branch: pkg_details.branch.clone(),
111 | tag: pkg_details.tag.clone(),
112 | rev: pkg_details.rev.clone(),
113 | path: pkg_details.path.clone(),
114 | default_features: pkg_details.default_features,
115 | features: pkg_details.features.clone(),
116 | });
117 | }
118 | } else {
119 | binary_details.push(BinaryPackage {
120 | bin_target: None,
121 | package: pkg_name,
122 | locked: pkg_details.locked,
123 | version: pkg_details.version,
124 | git: pkg_details.git,
125 | branch: pkg_details.branch,
126 | tag: pkg_details.tag,
127 | rev: pkg_details.rev,
128 | path: pkg_details.path,
129 | default_features: pkg_details.default_features,
130 | features: pkg_details.features,
131 | });
132 | }
133 | }
134 |
135 | binary_details.sort_by_key(|e| {
136 | if e.bin_target.is_some() {
137 | return e.bin_target.as_ref().unwrap().to_string();
138 | }
139 | return e.package.to_string();
140 | });
141 |
142 | return Ok(binary_details);
143 | }
144 |
--------------------------------------------------------------------------------
/src/metadata_test.rs:
--------------------------------------------------------------------------------
1 | use super::get_binary_packages;
2 |
3 | mod get_binary_packages {
4 | use super::*;
5 |
6 | #[test]
7 | fn it_returns_locked_packages() {
8 | let binary_packages = get_binary_packages().unwrap();
9 | let nextest = binary_packages
10 | .iter()
11 | .find(|&e| return e.package == "cargo-nextest");
12 |
13 | assert!(nextest.is_some());
14 | let res = nextest.unwrap();
15 | assert_eq!(&res.package, "cargo-nextest");
16 | assert_ne!(&res.version, "");
17 | assert!(res.locked.unwrap());
18 | }
19 |
20 | #[test]
21 | fn it_returns_bin_target_packages() {
22 | let binary_packages = get_binary_packages().unwrap();
23 | let android = binary_packages.iter().find(|&e| {
24 | return e.bin_target.is_some() && e.bin_target.clone().unwrap() == "hello-world-first";
25 | });
26 |
27 | assert!(android.is_some());
28 | let res = android.unwrap();
29 | assert_eq!(&res.package, "dustinblackman-hello-world");
30 | assert_ne!(&res.version, "");
31 | assert_eq!(
32 | &res.git,
33 | &Some("https://github.com/dustinblackman/rust-hello-world".to_string())
34 | );
35 | assert_eq!(res.bin_target.clone().unwrap(), "hello-world-first");
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/shims.rs:
--------------------------------------------------------------------------------
1 | use std::env;
2 | use std::fs;
3 | use std::io::Write;
4 | use std::path;
5 |
6 | use anyhow::Result;
7 | use cfg_if::cfg_if;
8 |
9 | use crate::metadata;
10 |
11 | #[cfg(target_family = "unix")]
12 | fn create_shim(binary: &str, bin_path: path::PathBuf) -> Result<()> {
13 | use std::os::unix::prelude::OpenOptionsExt;
14 |
15 | let mut shell = env::var("SHELL")
16 | .unwrap_or("bash".to_string())
17 | .split('/')
18 | .last()
19 | .unwrap()
20 | .to_string();
21 |
22 | if !["bash", "zsh", "sh"].contains(&&*shell) {
23 | shell = "sh".to_string();
24 | }
25 |
26 | let script = format!(
27 | r#"#!/usr/bin/env {shell}
28 |
29 | if [ ! -t 0 ]; then
30 | cat - | cargo bin {binary} "$@"
31 | else
32 | cargo bin {binary} "$@"
33 | fi"#
34 | );
35 |
36 | let mut f = fs::OpenOptions::new()
37 | .create(true)
38 | .write(true)
39 | .mode(0o770)
40 | .open(bin_path)?;
41 |
42 | write!(f, "{}", script)?;
43 |
44 | return Ok(());
45 | }
46 |
47 | #[cfg(not(target_family = "unix"))]
48 | fn create_shim(binary: &str, bin_path: path::PathBuf) -> Result<()> {
49 | let script = format!(
50 | r#"@echo off
51 | cargo bin {binary} %*
52 | "#
53 | );
54 |
55 | let mut f = fs::OpenOptions::new()
56 | .create(true)
57 | .write(true)
58 | .open(bin_path)?;
59 |
60 | write!(f, "{}", script)?;
61 |
62 | return Ok(());
63 | }
64 |
65 | /// Creates shims in `.bin/shims` for all non cargo extensions configured in
66 | /// Cargo.toml. This directory is added to PATH For all executes of `cargo bin`.
67 | pub fn sync() -> Result<()> {
68 | let bin_dir = metadata::get_project_root()?.join(".bin/.shims");
69 | if !bin_dir.exists() {
70 | fs::create_dir_all(&bin_dir)?;
71 | }
72 |
73 | for pkg in metadata::get_binary_packages()? {
74 | let mut bin = pkg.package;
75 | if let Some(bin_target) = pkg.bin_target {
76 | bin = bin_target;
77 | }
78 |
79 | if bin.starts_with("cargo-") {
80 | continue;
81 | }
82 |
83 | let mut bin_path = bin_dir.join(&bin);
84 | bin_path.set_extension("");
85 | cfg_if! {
86 | if #[cfg(not(target_family = "unix"))] {
87 | bin_path.set_extension("cmd");
88 | }
89 | }
90 | if bin_path.exists() {
91 | continue;
92 | }
93 |
94 | create_shim(&bin, bin_path)?;
95 | }
96 |
97 | return Ok(());
98 | }
99 |
100 | /// Return an array of entries that can be added to PATH to provide shims to
101 | /// other configured run-bin packages. Results be empty if entries already exist
102 | /// in PATH.
103 | pub fn get_shim_paths() -> Result> {
104 | let mut shim_paths = vec![];
105 | let system_shell_paths = env::var("PATH")
106 | .unwrap_or("".to_string())
107 | .split(':')
108 | .map(|e| return e.to_string())
109 | .collect::>();
110 |
111 | let project_root = metadata::get_project_root()?;
112 | let runbin = project_root
113 | .join(".bin/.shims")
114 | .to_string_lossy()
115 | .to_string();
116 |
117 | if !system_shell_paths.contains(&runbin) {
118 | shim_paths.push(runbin);
119 | }
120 |
121 | let gha = project_root.join(".gha/.shims");
122 | if gha.exists() && !system_shell_paths.contains(&gha.to_string_lossy().to_string()) {
123 | shim_paths.push(gha.to_string_lossy().to_string());
124 | }
125 |
126 | return Ok(shim_paths);
127 | }
128 |
--------------------------------------------------------------------------------
/tests/binary_test.rs:
--------------------------------------------------------------------------------
1 | mod install {
2 | use cargo_run_bin::binary::install;
3 | use cargo_run_bin::metadata;
4 | use cfg_if::cfg_if;
5 |
6 | #[test]
7 | fn it_returns_bin_path() {
8 | let binary_packages = metadata::get_binary_packages().unwrap();
9 | let nextest = binary_packages
10 | .iter()
11 | .find(|&e| e.package == "cargo-nextest")
12 | .unwrap();
13 |
14 | let cache_bin_path = install(nextest.clone()).unwrap();
15 |
16 | cfg_if! {
17 | if #[cfg(not(target_family = "unix"))] {
18 | assert!(cache_bin_path.ends_with("\\bin\\cargo-nextest.exe"));
19 | } else {
20 | assert!(cache_bin_path.ends_with("/bin/cargo-nextest"));
21 | }
22 | }
23 | }
24 | }
25 |
26 | mod cargo_install {
27 | use cargo_run_bin::binary::cargo_install;
28 | use cargo_run_bin::metadata;
29 |
30 | #[test]
31 | fn it_builds_successfully() {
32 | let res = cargo_install(
33 | metadata::BinaryPackage {
34 | bin_target: None,
35 | package: "dustinblackman-hello-world".to_string(),
36 | locked: None,
37 | version: "0.1.0".to_string(),
38 | git: None,
39 | branch: None,
40 | tag: None,
41 | rev: None,
42 | path: None,
43 | default_features: None,
44 | features: None,
45 | },
46 | "./.tmp".into(),
47 | );
48 |
49 | assert!(res.is_ok());
50 | }
51 |
52 | #[test]
53 | fn it_builds_successfully_with_git() {
54 | let res = cargo_install(
55 | metadata::BinaryPackage {
56 | bin_target: None,
57 | package: "dustinblackman-hello-world".to_string(),
58 | locked: None,
59 | version: "0.2.0".to_string(),
60 | git: Some("https://github.com/dustinblackman/rust-hello-world".to_string()),
61 | branch: None,
62 | tag: None,
63 | rev: None,
64 | path: None,
65 | default_features: None,
66 | features: None,
67 | },
68 | "./.tmp".into(),
69 | );
70 |
71 | assert!(res.is_ok());
72 | }
73 |
74 | #[test]
75 | fn it_builds_successfully_with_git_rev() {
76 | let res = cargo_install(
77 | metadata::BinaryPackage {
78 | bin_target: None,
79 | package: "dustinblackman-hello-world".to_string(),
80 | locked: None,
81 | version: "0.2.0".to_string(),
82 | git: Some("https://github.com/dustinblackman/rust-hello-world".to_string()),
83 | branch: None,
84 | tag: None,
85 | rev: Some("8a1cd3d2538460d1e8920bf86cf6e2aa982eb69d".to_string()),
86 | path: None,
87 | default_features: None,
88 | features: None,
89 | },
90 | "./.tmp".into(),
91 | );
92 |
93 | assert!(res.is_ok());
94 | }
95 |
96 | #[test]
97 | fn it_builds_successfully_with_git_branch() {
98 | let res = cargo_install(
99 | metadata::BinaryPackage {
100 | bin_target: None,
101 | package: "dustinblackman-hello-world".to_string(),
102 | locked: None,
103 | version: "0.2.0".to_string(),
104 | git: Some("https://github.com/dustinblackman/rust-hello-world".to_string()),
105 | branch: Some("testbranch".to_string()),
106 | tag: None,
107 | rev: None,
108 | path: None,
109 | default_features: None,
110 | features: None,
111 | },
112 | "./.tmp".into(),
113 | );
114 |
115 | assert!(res.is_ok());
116 | }
117 |
118 | #[test]
119 | fn it_builds_successfully_with_git_tag() {
120 | let res = cargo_install(
121 | metadata::BinaryPackage {
122 | bin_target: None,
123 | package: "dustinblackman-hello-world".to_string(),
124 | locked: None,
125 | version: "0.2.1".to_string(),
126 | git: Some("https://github.com/dustinblackman/rust-hello-world".to_string()),
127 | branch: None,
128 | tag: Some("v0.2.1".to_string()),
129 | rev: None,
130 | path: None,
131 | default_features: None,
132 | features: None,
133 | },
134 | "./.tmp".into(),
135 | );
136 |
137 | assert!(res.is_ok());
138 | }
139 |
140 | #[test]
141 | fn it_builds_successfully_with_path() {
142 | let res = cargo_install(
143 | metadata::BinaryPackage {
144 | bin_target: None,
145 | package: "cargo-run-bin".to_string(),
146 | locked: None,
147 | version: "1.4.1".to_string(),
148 | git: None,
149 | branch: None,
150 | tag: None,
151 | rev: None,
152 | path: Some(String::from(".")),
153 | default_features: None,
154 | features: None,
155 | },
156 | "./.tmp".into(),
157 | );
158 |
159 | assert!(res.is_ok());
160 | }
161 | }
162 |
163 | mod binstall {
164 | use cargo_run_bin::binary::binstall;
165 | use cargo_run_bin::metadata;
166 |
167 | #[test]
168 | fn it_builds_successfully() {
169 | let res = binstall(
170 | metadata::BinaryPackage {
171 | bin_target: None,
172 | package: "dustinblackman-hello-world".to_string(),
173 | locked: None,
174 | version: "0.1.0".to_string(),
175 | git: None,
176 | branch: None,
177 | tag: None,
178 | rev: None,
179 | path: None,
180 | default_features: None,
181 | features: None,
182 | },
183 | "./.tmp".into(),
184 | );
185 |
186 | assert!(res.is_ok());
187 | }
188 |
189 | #[test]
190 | fn it_builds_successfully_with_git() {
191 | let res = binstall(
192 | metadata::BinaryPackage {
193 | bin_target: None,
194 | package: "dustinblackman-hello-world".to_string(),
195 | locked: None,
196 | version: "0.1.0".to_string(),
197 | git: Some("https://github.com/dustinblackman/rust-hello-world".to_string()),
198 | branch: None,
199 | tag: None,
200 | rev: None,
201 | path: None,
202 | default_features: None,
203 | features: None,
204 | },
205 | "./.tmp".into(),
206 | );
207 |
208 | assert!(res.is_ok());
209 | }
210 | }
211 |
212 | mod run {
213 | use cargo_run_bin::binary::install;
214 | use cargo_run_bin::binary::run;
215 | use cargo_run_bin::metadata;
216 |
217 | #[test]
218 | fn it_runs_help_successfully() {
219 | let binary_packages = metadata::get_binary_packages().unwrap();
220 | let nextest = binary_packages
221 | .iter()
222 | .find(|&e| e.package == "cargo-nextest")
223 | .unwrap();
224 | let cache_bin_path = install(nextest.clone()).unwrap();
225 |
226 | let res = run(cache_bin_path, vec!["--help".to_string()]);
227 | assert!(res.is_ok());
228 | }
229 | }
230 |
--------------------------------------------------------------------------------
/tests/cargo_config_test.rs:
--------------------------------------------------------------------------------
1 | mod sync_aliases {
2 | use std::fs;
3 |
4 | use cargo_run_bin::cargo_config::sync_aliases;
5 |
6 | #[test]
7 | fn it_removes_and_adds_aliases() {
8 | let res = sync_aliases();
9 | let toml_str: String = fs::read_to_string(".cargo/config.toml")
10 | .unwrap()
11 | .parse()
12 | .unwrap();
13 |
14 | assert!(res.is_ok());
15 | assert!(toml_str.contains("nextest = [\"bin\", \"cargo-nextest\"]"));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/tests/cli_integration_test.rs:
--------------------------------------------------------------------------------
1 | mod direct {
2 | use assert_cmd::Command;
3 |
4 | #[test]
5 | fn it_syncs_aliases_successfully() {
6 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
7 | let assert = cmd.arg("--sync-aliases").assert();
8 |
9 | let res = assert.success();
10 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
11 | insta::assert_snapshot!(stdout, @r###"
12 | [32mDone![0m
13 | "###);
14 | }
15 |
16 | #[test]
17 | fn it_install_all_bins_successfully() {
18 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
19 | let assert = cmd.arg("--install").assert();
20 |
21 | let res = assert.success();
22 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
23 | insta::assert_snapshot!(stdout, @r###"
24 | [32mDone![0m
25 | "###);
26 | }
27 |
28 | #[test]
29 | fn it_builds_all_bins_successfully() {
30 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
31 | let assert = cmd.arg("--build").assert();
32 |
33 | let res = assert.success();
34 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
35 | insta::assert_snapshot!(stdout, @r###"
36 | [32mDone![0m
37 | "###);
38 | }
39 |
40 | #[test]
41 | fn it_runs_help_successfully() {
42 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
43 | let assert = cmd.arg("--help").assert();
44 |
45 | let res = assert.success();
46 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
47 | assert!(stdout.contains(env!("CARGO_PKG_DESCRIPTION")));
48 | }
49 |
50 | #[test]
51 | fn it_runs_nextest_help_successfully() {
52 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
53 | let assert = cmd.arg("cargo-nextest").arg("--help").assert();
54 |
55 | let res = assert.success();
56 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
57 | assert!(stdout.contains("cargo nextest"));
58 | }
59 |
60 | #[test]
61 | fn it_fails_when_binary_is_not_configured() {
62 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
63 | let assert = cmd.arg("not-real").assert();
64 |
65 | let res = assert.failure();
66 | let stderr = String::from_utf8(res.get_output().stderr.clone()).unwrap();
67 | insta::assert_snapshot!(stderr, @r###"
68 | [31mrun-bin failed: No package found for binary not-real[0m
69 | "###);
70 | }
71 | }
72 |
73 | mod bin_prefix {
74 | use assert_cmd::Command;
75 |
76 | #[test]
77 | fn it_syncs_aliases_successfully() {
78 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
79 | let assert = cmd.arg("bin").arg("--sync-aliases").assert();
80 |
81 | let res = assert.success();
82 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
83 | insta::assert_snapshot!(stdout, @r###"
84 | [32mDone![0m
85 | "###);
86 | }
87 |
88 | #[test]
89 | fn it_install_all_bins_successfully() {
90 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
91 | let assert = cmd.arg("bin").arg("--install").assert();
92 |
93 | let res = assert.success();
94 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
95 | insta::assert_snapshot!(stdout, @r###"
96 | [32mDone![0m
97 | "###);
98 | }
99 |
100 | #[test]
101 | fn it_builds_all_bins_successfully() {
102 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
103 | let assert = cmd.arg("bin").arg("--build").assert();
104 |
105 | let res = assert.success();
106 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
107 | insta::assert_snapshot!(stdout, @r###"
108 | [32mDone![0m
109 | "###);
110 | }
111 |
112 | #[test]
113 | fn it_runs_nextest_help_successfully() {
114 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
115 | let assert = cmd.arg("bin").arg("cargo-nextest").arg("--help").assert();
116 |
117 | let res = assert.success();
118 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
119 | assert!(stdout.contains("cargo nextest"));
120 | }
121 |
122 | #[test]
123 | fn it_runs_help_successfully() {
124 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
125 | let assert = cmd.arg("bin").arg("--help").assert();
126 |
127 | let res = assert.success();
128 | let stdout = String::from_utf8(res.get_output().stdout.clone()).unwrap();
129 | assert!(stdout.contains(env!("CARGO_PKG_DESCRIPTION")));
130 | }
131 |
132 | #[test]
133 | fn it_fails_when_binary_is_not_configured() {
134 | let mut cmd = Command::cargo_bin("cargo-bin").unwrap();
135 | let assert = cmd.arg("bin").arg("not-real").assert();
136 |
137 | let res = assert.failure();
138 | let stderr = String::from_utf8(res.get_output().stderr.clone()).unwrap();
139 | insta::assert_snapshot!(stderr, @r###"
140 | [31mrun-bin failed: No package found for binary not-real[0m
141 | "###);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/tests/shims_test.rs:
--------------------------------------------------------------------------------
1 | use std::fs;
2 |
3 | use anyhow::Result;
4 | use cargo_run_bin::metadata;
5 |
6 | fn clean_shims() -> Result<()> {
7 | let bin_dir = metadata::get_project_root()?.join(".bin/.shims");
8 | if bin_dir.exists() {
9 | fs::remove_dir_all(&bin_dir)?;
10 | }
11 |
12 | Ok(())
13 | }
14 |
15 | mod sync_shims {
16 | use std::fs;
17 |
18 | use cargo_run_bin::metadata;
19 | use cargo_run_bin::shims::sync;
20 |
21 | use super::clean_shims;
22 |
23 | #[test]
24 | #[cfg(target_family = "unix")]
25 | fn it_creates_shims() {
26 | clean_shims().unwrap();
27 | let res = sync();
28 | let exists = metadata::get_project_root()
29 | .unwrap()
30 | .join(".bin/.shims/hello-world-first")
31 | .exists();
32 |
33 | clean_shims().unwrap();
34 | assert!(res.is_ok());
35 | assert!(exists);
36 | }
37 |
38 | #[test]
39 | #[cfg(target_family = "unix")]
40 | fn it_creates_shims_for_zsh() {
41 | std::env::set_var("SHELL", "zsh");
42 | clean_shims().unwrap();
43 | let res = sync();
44 | assert!(res.is_ok());
45 |
46 | let shim_path = metadata::get_project_root()
47 | .unwrap()
48 | .join(".bin/.shims/hello-world-first");
49 |
50 | let content = fs::read_to_string(shim_path).unwrap();
51 |
52 | clean_shims().unwrap();
53 | assert!(content.starts_with("#!/usr/bin/env zsh"));
54 | }
55 |
56 | #[test]
57 | #[cfg(target_family = "unix")]
58 | fn it_creates_shims_falling_back_to_sh() {
59 | std::env::set_var("SHELL", "fish");
60 | clean_shims().unwrap();
61 | let res = sync();
62 | assert!(res.is_ok());
63 |
64 | let shim_path = metadata::get_project_root()
65 | .unwrap()
66 | .join(".bin/.shims/hello-world-first");
67 |
68 | let content = fs::read_to_string(shim_path).unwrap();
69 |
70 | clean_shims().unwrap();
71 | assert!(content.starts_with("#!/usr/bin/env sh"));
72 | }
73 |
74 | #[test]
75 | #[cfg(not(target_family = "unix"))]
76 | fn it_creates_shims() {
77 | let res = sync();
78 | let exists = metadata::get_project_root()
79 | .unwrap()
80 | .join(".bin/.shims/hello-world-first.cmd")
81 | .exists();
82 |
83 | assert!(res.is_ok());
84 | assert!(exists);
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/tools/cargo-bin/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "cargo-bin"
3 |
4 | [dependencies]
5 | cargo-run-bin = { version = "1.7.4", features = ["cli"]}
--------------------------------------------------------------------------------
/tools/cargo-bin/src/main.rs:
--------------------------------------------------------------------------------
1 | use std::process;
2 |
3 | fn main() {
4 | let res = cargo_run_bin::cli::run();
5 |
6 | // Only reached if run-bin code fails, otherwise process exits early from within
7 | // binary::run.
8 | if let Err(res) = res {
9 | eprintln!("\x1b[31m{}\x1b[0m", format!("run-bin failed: {res}"));
10 | process::exit(1);
11 | }
12 | }
13 |
--------------------------------------------------------------------------------