├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── dependabot.yml └── workflows │ ├── linux.yml │ ├── macos.yml │ └── windows.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── fleet.toml ├── installer ├── .cargo │ └── config.toml ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── fleet.toml ├── install.sh └── src │ └── main.rs ├── src ├── cli │ ├── app.rs │ ├── help.rs │ ├── mod.rs │ └── prompt │ │ ├── input.rs │ │ ├── mod.rs │ │ └── prompts.rs ├── core │ ├── commands │ │ ├── bloat.rs │ │ ├── build.rs │ │ ├── configure.rs │ │ ├── init.rs │ │ ├── mod.rs │ │ ├── run.rs │ │ └── udeps.rs │ ├── config │ │ ├── cargo.rs │ │ ├── enable.rs │ │ ├── global.rs │ │ └── mod.rs │ └── mod.rs ├── main.rs └── utils │ ├── configure.rs │ └── mod.rs └── todo.md /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: 'bug' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | 29 | **Additional context** 30 | Add any other context about the problem here. 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 'enhancement' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | # To get started with Dependabot version updates, you'll need to specify which 2 | # package ecosystems to update and where the package manifests are located. 3 | # Please see the documentation for all configuration options: 4 | # https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates 5 | 6 | version: 2 7 | updates: 8 | - package-ecosystem: "" # See documentation for possible values 9 | directory: "/" # Location of package manifests 10 | schedule: 11 | interval: "daily" 12 | -------------------------------------------------------------------------------- /.github/workflows/linux.yml: -------------------------------------------------------------------------------- 1 | name: Linux Builds 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: ubuntu-latest 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | # selecting a toolchain either by action or manual `rustup` calls should happen 20 | # before the plugin, as it uses the current rustc version as its cache key 21 | - uses: actions-rs/toolchain@v1 22 | with: 23 | toolchain: nightly 24 | components: clippy 25 | override: true 26 | 27 | - name: Set up Clang 28 | uses: egor-tensin/setup-clang@v1 29 | with: 30 | version: latest 31 | platform: x64 32 | 33 | - uses: Swatinem/rust-cache@v1 34 | 35 | - name: Install sccache 36 | run: if [ -e ~/.cargo/bin/sccache ] ; then echo "Sccache is already installed"; else cargo install sccache -f; fi 37 | 38 | - name: Install fleet 39 | run: cargo install --path . fleet-rs -f 40 | 41 | - name: Run app using fleet 42 | run: fleet build -- --bin fleet 43 | 44 | - name: Install cargo bloat 45 | run: cargo install cargo-bloat 46 | 47 | - name: Run bloat analysis 48 | run: fleet bloat 49 | -------------------------------------------------------------------------------- /.github/workflows/macos.yml: -------------------------------------------------------------------------------- 1 | name: Macos Builds 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: macos-11 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | # selecting a toolchain either by action or manual `rustup` calls should happen 20 | # before the plugin, as it uses the current rustc version as its cache key 21 | - uses: actions-rs/toolchain@v1 22 | with: 23 | toolchain: nightly 24 | components: clippy 25 | override: true 26 | 27 | - name: Cache .cargo/bin 28 | uses: actions/cache@v3 29 | env: 30 | cache-name: cache-cargo-dir 31 | with: 32 | path: /Users/runner/.cargo/bin/ 33 | key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/cargo.lock') }} 34 | restore-keys: | 35 | ${{ runner.os }}-build-${{ env.cache-name }}- 36 | ${{ runner.os }}-build- 37 | ${{ runner.os }}- 38 | 39 | - name: Install sccache 40 | run: if [ -e ~/.cargo/bin/sccache ] ; then echo "Sccache is already installed"; else cargo install sccache -f; fi 41 | 42 | - name: Install zld 43 | run: if [ -e /usr/local/bin/zld ]; then brew link zld; else brew install michaeleisel/zld/zld; fi 44 | 45 | - name: Install fleet 46 | run: cargo install --path . fleet-rs -f 47 | 48 | - name: Run app using fleet 49 | run: fleet build -- --bin fleet 50 | 51 | - name: Install cargo bloat 52 | run: if [ -e ~/.cargo/bin/cargo-bloat ] ; then echo "Bloat is already installed"; else cargo install cargo-bloat -f; fi 53 | 54 | - name: Run bloat analysis 55 | run: fleet bloat 56 | -------------------------------------------------------------------------------- /.github/workflows/windows.yml: -------------------------------------------------------------------------------- 1 | name: Windows builds 2 | 3 | on: 4 | push: 5 | branches: [master] 6 | pull_request: 7 | branches: [master] 8 | 9 | env: 10 | CARGO_TERM_COLOR: always 11 | 12 | jobs: 13 | build: 14 | runs-on: windows-2022 15 | 16 | steps: 17 | - uses: actions/checkout@v3 18 | 19 | # selecting a toolchain either by action or manual `rustup` calls should happen 20 | # before the plugin, as it uses the current rustc version as its cache key 21 | - uses: actions-rs/toolchain@v1 22 | with: 23 | toolchain: nightly 24 | components: clippy 25 | override: true 26 | 27 | - uses: Swatinem/rust-cache@v1 28 | 29 | - name: Install sccache 30 | run: if (Test-Path -Path ~\.cargo\bin\sccache.exe -PathType Leaf) {echo "Sccache is already installed"} else { cargo install sccache -f } 31 | 32 | - name: Install fleet 33 | run: cargo install --path . fleet-rs -f 34 | 35 | - name: Run app using fleet 36 | run: fleet build -- --bin fleet 37 | 38 | - name: Install cargo bloat 39 | run: cargo install cargo-bloat 40 | 41 | - name: Run bloat analysis 42 | run: fleet bloat 43 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | installer/target 3 | # You can't build fleet without fleet already installed if we have the .cargo directory with optimizations 4 | .cargo/ 5 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | team@dimension.dev. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to Fleet 2 | 3 | We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: 4 | 5 | - Reporting a bug 6 | - Discussing the current state of the code 7 | - Submitting a fix 8 | - Proposing new features 9 | - Becoming a maintainer 10 | 11 | ## We Develop with Github 12 | 13 | We use github to host code, to track issues and feature requests, as well as accept pull requests. 14 | 15 | ## We Use [Github Flow](https://guides.github.com/introduction/flow/index.html), So All Code Changes Happen Through Pull Requests 16 | 17 | Pull requests are the best way to propose changes to the codebase (we use [Github Flow](https://guides.github.com/introduction/flow/index.html)). We actively welcome your pull requests: 18 | 19 | 1. Fork the repo and create your branch from `master`. 20 | 2. If you've added code that should be tested, add tests. 21 | 3. If you've changed APIs, update the documentation. 22 | 4. Ensure the test suite passes. 23 | 5. Make sure your code lints. 24 | 6. Issue that pull request! 25 | 26 | ## Any contributions you make will be under the Apache 2.0 License 27 | 28 | In short, when you submit code changes, your submissions are understood to be under the same [Apache 2.0 License](https://choosealicense.com/licenses/apache-2.0) that covers the project. Feel free to contact the maintainers if that's a concern. 29 | 30 | ## Report bugs using Github's [issues](https://github.com/dimensionhq/fleet/issues) 31 | 32 | We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/dimensionhq/fleet/issues/new); it's that easy! 33 | 34 | ## Write bug reports with detail, background, and sample code 35 | 36 | **Great Bug Reports** tend to have: 37 | 38 | - A quick summary and/or background 39 | - Steps to reproduce 40 | - Be specific! 41 | - Give sample code if you can. 42 | - What you expected would happen 43 | - What actually happens 44 | - Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) 45 | 46 | ## License 47 | 48 | By contributing, you agree that your contributions will be licensed under its Apache 2.0 License. 49 | 50 | ## References 51 | 52 | This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/a9316a723f9e918afde44dea68b5f9f39b7d9b00/CONTRIBUTING.md) 53 | -------------------------------------------------------------------------------- /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 = "addr2line" 7 | version = "0.17.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "0.7.18" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "ansi_term" 31 | version = "0.12.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" 34 | dependencies = [ 35 | "winapi", 36 | ] 37 | 38 | [[package]] 39 | name = "anyhow" 40 | version = "1.0.57" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "08f9b8508dccb7687a1d6c4ce66b2b0ecef467c94667de27d8d7fe1f8d2a9cdc" 43 | 44 | [[package]] 45 | name = "arrayvec" 46 | version = "0.5.2" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" 49 | 50 | [[package]] 51 | name = "atty" 52 | version = "0.2.14" 53 | source = "registry+https://github.com/rust-lang/crates.io-index" 54 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 55 | dependencies = [ 56 | "hermit-abi", 57 | "libc", 58 | "winapi", 59 | ] 60 | 61 | [[package]] 62 | name = "autocfg" 63 | version = "1.1.0" 64 | source = "registry+https://github.com/rust-lang/crates.io-index" 65 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 66 | 67 | [[package]] 68 | name = "backtrace" 69 | version = "0.3.65" 70 | source = "registry+https://github.com/rust-lang/crates.io-index" 71 | checksum = "11a17d453482a265fd5f8479f2a3f405566e6ca627837aaddb85af8b1ab8ef61" 72 | dependencies = [ 73 | "addr2line", 74 | "cc", 75 | "cfg-if", 76 | "libc", 77 | "miniz_oxide", 78 | "object", 79 | "rustc-demangle", 80 | ] 81 | 82 | [[package]] 83 | name = "bitflags" 84 | version = "1.3.2" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 87 | 88 | [[package]] 89 | name = "byte-unit" 90 | version = "4.0.14" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | checksum = "95ebf10dda65f19ff0f42ea15572a359ed60d7fc74fdc984d90310937be0014b" 93 | dependencies = [ 94 | "utf8-width", 95 | ] 96 | 97 | [[package]] 98 | name = "cargo-util" 99 | version = "0.1.2" 100 | source = "registry+https://github.com/rust-lang/crates.io-index" 101 | checksum = "a51c783163bdf4549820b80968d386c94ed45ed23819c93f59cca7ebd97fe0eb" 102 | dependencies = [ 103 | "anyhow", 104 | "core-foundation", 105 | "crypto-hash", 106 | "filetime", 107 | "hex 0.4.3", 108 | "jobserver", 109 | "libc", 110 | "log", 111 | "miow", 112 | "same-file", 113 | "shell-escape", 114 | "tempfile", 115 | "walkdir", 116 | "winapi", 117 | ] 118 | 119 | [[package]] 120 | name = "cc" 121 | version = "1.0.73" 122 | source = "registry+https://github.com/rust-lang/crates.io-index" 123 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 124 | 125 | [[package]] 126 | name = "cfg-if" 127 | version = "1.0.0" 128 | source = "registry+https://github.com/rust-lang/crates.io-index" 129 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 130 | 131 | [[package]] 132 | name = "clap" 133 | version = "3.1.18" 134 | source = "registry+https://github.com/rust-lang/crates.io-index" 135 | checksum = "d2dbdf4bdacb33466e854ce889eee8dfd5729abf7ccd7664d0a2d60cd384440b" 136 | dependencies = [ 137 | "atty", 138 | "bitflags", 139 | "clap_lex", 140 | "indexmap", 141 | "lazy_static 1.4.0", 142 | "termcolor", 143 | "textwrap", 144 | ] 145 | 146 | [[package]] 147 | name = "clap_lex" 148 | version = "0.2.0" 149 | source = "registry+https://github.com/rust-lang/crates.io-index" 150 | checksum = "a37c35f1112dad5e6e0b1adaff798507497a18fceeb30cceb3bae7d1427b9213" 151 | dependencies = [ 152 | "os_str_bytes", 153 | ] 154 | 155 | [[package]] 156 | name = "colored" 157 | version = "2.0.0" 158 | source = "registry+https://github.com/rust-lang/crates.io-index" 159 | checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd" 160 | dependencies = [ 161 | "atty", 162 | "lazy_static 1.4.0", 163 | "winapi", 164 | ] 165 | 166 | [[package]] 167 | name = "comfy-table" 168 | version = "6.0.0" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "121d8a5b0346092c18a4b2fd6f620d7a06f0eb7ac0a45860939a0884bc579c56" 171 | dependencies = [ 172 | "crossterm", 173 | "strum", 174 | "strum_macros", 175 | "unicode-width", 176 | ] 177 | 178 | [[package]] 179 | name = "commoncrypto" 180 | version = "0.2.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "d056a8586ba25a1e4d61cb090900e495952c7886786fc55f909ab2f819b69007" 183 | dependencies = [ 184 | "commoncrypto-sys", 185 | ] 186 | 187 | [[package]] 188 | name = "commoncrypto-sys" 189 | version = "0.2.0" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "1fed34f46747aa73dfaa578069fd8279d2818ade2b55f38f22a9401c7f4083e2" 192 | dependencies = [ 193 | "libc", 194 | ] 195 | 196 | [[package]] 197 | name = "config" 198 | version = "0.11.0" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "1b1b9d958c2b1368a663f05538fc1b5975adce1e19f435acceae987aceeeb369" 201 | dependencies = [ 202 | "lazy_static 1.4.0", 203 | "nom", 204 | "rust-ini", 205 | "serde 1.0.136", 206 | "serde-hjson", 207 | "serde_json", 208 | "toml", 209 | "yaml-rust", 210 | ] 211 | 212 | [[package]] 213 | name = "console" 214 | version = "0.15.0" 215 | source = "registry+https://github.com/rust-lang/crates.io-index" 216 | checksum = "a28b32d32ca44b70c3e4acd7db1babf555fa026e385fb95f18028f88848b3c31" 217 | dependencies = [ 218 | "encode_unicode", 219 | "libc", 220 | "once_cell", 221 | "regex", 222 | "terminal_size", 223 | "unicode-width", 224 | "winapi", 225 | ] 226 | 227 | [[package]] 228 | name = "core-foundation" 229 | version = "0.9.3" 230 | source = "registry+https://github.com/rust-lang/crates.io-index" 231 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 232 | dependencies = [ 233 | "core-foundation-sys", 234 | "libc", 235 | ] 236 | 237 | [[package]] 238 | name = "core-foundation-sys" 239 | version = "0.8.3" 240 | source = "registry+https://github.com/rust-lang/crates.io-index" 241 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 242 | 243 | [[package]] 244 | name = "crossbeam-channel" 245 | version = "0.5.4" 246 | source = "registry+https://github.com/rust-lang/crates.io-index" 247 | checksum = "5aaa7bd5fb665c6864b5f963dd9097905c54125909c7aa94c9e18507cdbe6c53" 248 | dependencies = [ 249 | "cfg-if", 250 | "crossbeam-utils", 251 | ] 252 | 253 | [[package]] 254 | name = "crossbeam-deque" 255 | version = "0.8.1" 256 | source = "registry+https://github.com/rust-lang/crates.io-index" 257 | checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" 258 | dependencies = [ 259 | "cfg-if", 260 | "crossbeam-epoch", 261 | "crossbeam-utils", 262 | ] 263 | 264 | [[package]] 265 | name = "crossbeam-epoch" 266 | version = "0.9.8" 267 | source = "registry+https://github.com/rust-lang/crates.io-index" 268 | checksum = "1145cf131a2c6ba0615079ab6a638f7e1973ac9c2634fcbeaaad6114246efe8c" 269 | dependencies = [ 270 | "autocfg", 271 | "cfg-if", 272 | "crossbeam-utils", 273 | "lazy_static 1.4.0", 274 | "memoffset", 275 | "scopeguard", 276 | ] 277 | 278 | [[package]] 279 | name = "crossbeam-utils" 280 | version = "0.8.8" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "0bf124c720b7686e3c2663cf54062ab0f68a88af2fb6a030e87e30bf721fcb38" 283 | dependencies = [ 284 | "cfg-if", 285 | "lazy_static 1.4.0", 286 | ] 287 | 288 | [[package]] 289 | name = "crossterm" 290 | version = "0.23.2" 291 | source = "registry+https://github.com/rust-lang/crates.io-index" 292 | checksum = "a2102ea4f781910f8a5b98dd061f4c2023f479ce7bb1236330099ceb5a93cf17" 293 | dependencies = [ 294 | "bitflags", 295 | "crossterm_winapi", 296 | "libc", 297 | "mio", 298 | "parking_lot", 299 | "signal-hook", 300 | "signal-hook-mio", 301 | "winapi", 302 | ] 303 | 304 | [[package]] 305 | name = "crossterm_winapi" 306 | version = "0.9.0" 307 | source = "registry+https://github.com/rust-lang/crates.io-index" 308 | checksum = "2ae1b35a484aa10e07fe0638d02301c5ad24de82d310ccbd2f3693da5f09bf1c" 309 | dependencies = [ 310 | "winapi", 311 | ] 312 | 313 | [[package]] 314 | name = "crypto-hash" 315 | version = "0.3.4" 316 | source = "registry+https://github.com/rust-lang/crates.io-index" 317 | checksum = "8a77162240fd97248d19a564a565eb563a3f592b386e4136fb300909e67dddca" 318 | dependencies = [ 319 | "commoncrypto", 320 | "hex 0.3.2", 321 | "openssl", 322 | "winapi", 323 | ] 324 | 325 | [[package]] 326 | name = "dialoguer" 327 | version = "0.10.0" 328 | source = "registry+https://github.com/rust-lang/crates.io-index" 329 | checksum = "349d6b4fabcd9e97e1df1ae15395ac7e49fb144946a0d453959dc2696273b9da" 330 | dependencies = [ 331 | "console", 332 | "tempfile", 333 | "zeroize", 334 | ] 335 | 336 | [[package]] 337 | name = "directories" 338 | version = "4.0.1" 339 | source = "registry+https://github.com/rust-lang/crates.io-index" 340 | checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" 341 | dependencies = [ 342 | "dirs-sys", 343 | ] 344 | 345 | [[package]] 346 | name = "dirs" 347 | version = "4.0.0" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" 350 | dependencies = [ 351 | "dirs-sys", 352 | ] 353 | 354 | [[package]] 355 | name = "dirs-sys" 356 | version = "0.3.7" 357 | source = "registry+https://github.com/rust-lang/crates.io-index" 358 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 359 | dependencies = [ 360 | "libc", 361 | "redox_users", 362 | "winapi", 363 | ] 364 | 365 | [[package]] 366 | name = "either" 367 | version = "1.6.1" 368 | source = "registry+https://github.com/rust-lang/crates.io-index" 369 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 370 | 371 | [[package]] 372 | name = "encode_unicode" 373 | version = "0.3.6" 374 | source = "registry+https://github.com/rust-lang/crates.io-index" 375 | checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" 376 | 377 | [[package]] 378 | name = "fastrand" 379 | version = "1.7.0" 380 | source = "registry+https://github.com/rust-lang/crates.io-index" 381 | checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" 382 | dependencies = [ 383 | "instant", 384 | ] 385 | 386 | [[package]] 387 | name = "filetime" 388 | version = "0.2.16" 389 | source = "registry+https://github.com/rust-lang/crates.io-index" 390 | checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c" 391 | dependencies = [ 392 | "cfg-if", 393 | "libc", 394 | "redox_syscall", 395 | "winapi", 396 | ] 397 | 398 | [[package]] 399 | name = "fixedbitset" 400 | version = "0.4.1" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "279fb028e20b3c4c320317955b77c5e0c9701f05a1d309905d6fc702cdc5053e" 403 | 404 | [[package]] 405 | name = "fleet-rs" 406 | version = "0.0.8" 407 | dependencies = [ 408 | "ansi_term", 409 | "anyhow", 410 | "byte-unit", 411 | "cargo-util", 412 | "clap", 413 | "colored", 414 | "comfy-table", 415 | "dialoguer", 416 | "dirs", 417 | "human-panic", 418 | "indicatif", 419 | "ptree", 420 | "rustc_version", 421 | "serde 1.0.136", 422 | "serde_json", 423 | "sys-info", 424 | "sysinfo", 425 | "toml", 426 | "uuid 1.0.0", 427 | "which", 428 | "wsl", 429 | ] 430 | 431 | [[package]] 432 | name = "foreign-types" 433 | version = "0.3.2" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 436 | dependencies = [ 437 | "foreign-types-shared", 438 | ] 439 | 440 | [[package]] 441 | name = "foreign-types-shared" 442 | version = "0.1.1" 443 | source = "registry+https://github.com/rust-lang/crates.io-index" 444 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 445 | 446 | [[package]] 447 | name = "getrandom" 448 | version = "0.2.6" 449 | source = "registry+https://github.com/rust-lang/crates.io-index" 450 | checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad" 451 | dependencies = [ 452 | "cfg-if", 453 | "libc", 454 | "wasi 0.10.2+wasi-snapshot-preview1", 455 | ] 456 | 457 | [[package]] 458 | name = "gimli" 459 | version = "0.26.1" 460 | source = "registry+https://github.com/rust-lang/crates.io-index" 461 | checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4" 462 | 463 | [[package]] 464 | name = "hashbrown" 465 | version = "0.11.2" 466 | source = "registry+https://github.com/rust-lang/crates.io-index" 467 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 468 | 469 | [[package]] 470 | name = "heck" 471 | version = "0.4.0" 472 | source = "registry+https://github.com/rust-lang/crates.io-index" 473 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 474 | 475 | [[package]] 476 | name = "hermit-abi" 477 | version = "0.1.19" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 480 | dependencies = [ 481 | "libc", 482 | ] 483 | 484 | [[package]] 485 | name = "hex" 486 | version = "0.3.2" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77" 489 | 490 | [[package]] 491 | name = "hex" 492 | version = "0.4.3" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 495 | 496 | [[package]] 497 | name = "human-panic" 498 | version = "1.0.3" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "39f357a500abcbd7c5f967c1d45c8838585b36743823b9d43488f24850534e36" 501 | dependencies = [ 502 | "backtrace", 503 | "os_type", 504 | "serde 1.0.136", 505 | "serde_derive", 506 | "termcolor", 507 | "toml", 508 | "uuid 0.8.2", 509 | ] 510 | 511 | [[package]] 512 | name = "indexmap" 513 | version = "1.8.1" 514 | source = "registry+https://github.com/rust-lang/crates.io-index" 515 | checksum = "0f647032dfaa1f8b6dc29bd3edb7bbef4861b8b8007ebb118d6db284fd59f6ee" 516 | dependencies = [ 517 | "autocfg", 518 | "hashbrown", 519 | ] 520 | 521 | [[package]] 522 | name = "indicatif" 523 | version = "0.16.2" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | checksum = "2d207dc617c7a380ab07ff572a6e52fa202a2a8f355860ac9c38e23f8196be1b" 526 | dependencies = [ 527 | "console", 528 | "lazy_static 1.4.0", 529 | "number_prefix", 530 | "regex", 531 | ] 532 | 533 | [[package]] 534 | name = "instant" 535 | version = "0.1.12" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 538 | dependencies = [ 539 | "cfg-if", 540 | ] 541 | 542 | [[package]] 543 | name = "itoa" 544 | version = "1.0.2" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" 547 | 548 | [[package]] 549 | name = "jobserver" 550 | version = "0.1.24" 551 | source = "registry+https://github.com/rust-lang/crates.io-index" 552 | checksum = "af25a77299a7f711a01975c35a6a424eb6862092cc2d6c72c4ed6cbc56dfc1fa" 553 | dependencies = [ 554 | "libc", 555 | ] 556 | 557 | [[package]] 558 | name = "lazy_static" 559 | version = "0.2.11" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73" 562 | 563 | [[package]] 564 | name = "lazy_static" 565 | version = "1.4.0" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 568 | 569 | [[package]] 570 | name = "lexical-core" 571 | version = "0.7.6" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "6607c62aa161d23d17a9072cc5da0be67cdfc89d3afb1e8d9c842bebc2525ffe" 574 | dependencies = [ 575 | "arrayvec", 576 | "bitflags", 577 | "cfg-if", 578 | "ryu", 579 | "static_assertions", 580 | ] 581 | 582 | [[package]] 583 | name = "libc" 584 | version = "0.2.123" 585 | source = "registry+https://github.com/rust-lang/crates.io-index" 586 | checksum = "cb691a747a7ab48abc15c5b42066eaafde10dc427e3b6ee2a1cf43db04c763bd" 587 | 588 | [[package]] 589 | name = "linked-hash-map" 590 | version = "0.5.4" 591 | source = "registry+https://github.com/rust-lang/crates.io-index" 592 | checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" 593 | 594 | [[package]] 595 | name = "lock_api" 596 | version = "0.4.7" 597 | source = "registry+https://github.com/rust-lang/crates.io-index" 598 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 599 | dependencies = [ 600 | "autocfg", 601 | "scopeguard", 602 | ] 603 | 604 | [[package]] 605 | name = "log" 606 | version = "0.4.17" 607 | source = "registry+https://github.com/rust-lang/crates.io-index" 608 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 609 | dependencies = [ 610 | "cfg-if", 611 | ] 612 | 613 | [[package]] 614 | name = "memchr" 615 | version = "2.5.0" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 618 | 619 | [[package]] 620 | name = "memoffset" 621 | version = "0.6.5" 622 | source = "registry+https://github.com/rust-lang/crates.io-index" 623 | checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce" 624 | dependencies = [ 625 | "autocfg", 626 | ] 627 | 628 | [[package]] 629 | name = "miniz_oxide" 630 | version = "0.5.3" 631 | source = "registry+https://github.com/rust-lang/crates.io-index" 632 | checksum = "6f5c75688da582b8ffc1f1799e9db273f32133c49e048f614d22ec3256773ccc" 633 | dependencies = [ 634 | "adler", 635 | ] 636 | 637 | [[package]] 638 | name = "mio" 639 | version = "0.8.3" 640 | source = "registry+https://github.com/rust-lang/crates.io-index" 641 | checksum = "713d550d9b44d89174e066b7a6217ae06234c10cb47819a88290d2b353c31799" 642 | dependencies = [ 643 | "libc", 644 | "log", 645 | "wasi 0.11.0+wasi-snapshot-preview1", 646 | "windows-sys", 647 | ] 648 | 649 | [[package]] 650 | name = "miow" 651 | version = "0.3.7" 652 | source = "registry+https://github.com/rust-lang/crates.io-index" 653 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" 654 | dependencies = [ 655 | "winapi", 656 | ] 657 | 658 | [[package]] 659 | name = "nom" 660 | version = "5.1.2" 661 | source = "registry+https://github.com/rust-lang/crates.io-index" 662 | checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af" 663 | dependencies = [ 664 | "lexical-core", 665 | "memchr", 666 | "version_check", 667 | ] 668 | 669 | [[package]] 670 | name = "ntapi" 671 | version = "0.3.7" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "c28774a7fd2fbb4f0babd8237ce554b73af68021b5f695a3cebd6c59bac0980f" 674 | dependencies = [ 675 | "winapi", 676 | ] 677 | 678 | [[package]] 679 | name = "num-traits" 680 | version = "0.1.43" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" 683 | dependencies = [ 684 | "num-traits 0.2.15", 685 | ] 686 | 687 | [[package]] 688 | name = "num-traits" 689 | version = "0.2.15" 690 | source = "registry+https://github.com/rust-lang/crates.io-index" 691 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 692 | dependencies = [ 693 | "autocfg", 694 | ] 695 | 696 | [[package]] 697 | name = "num_cpus" 698 | version = "1.13.1" 699 | source = "registry+https://github.com/rust-lang/crates.io-index" 700 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 701 | dependencies = [ 702 | "hermit-abi", 703 | "libc", 704 | ] 705 | 706 | [[package]] 707 | name = "number_prefix" 708 | version = "0.4.0" 709 | source = "registry+https://github.com/rust-lang/crates.io-index" 710 | checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3" 711 | 712 | [[package]] 713 | name = "object" 714 | version = "0.28.4" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "e42c982f2d955fac81dd7e1d0e1426a7d702acd9c98d19ab01083a6a0328c424" 717 | dependencies = [ 718 | "memchr", 719 | ] 720 | 721 | [[package]] 722 | name = "once_cell" 723 | version = "1.10.0" 724 | source = "registry+https://github.com/rust-lang/crates.io-index" 725 | checksum = "87f3e037eac156d1775da914196f0f37741a274155e34a0b7e427c35d2a2ecb9" 726 | 727 | [[package]] 728 | name = "openssl" 729 | version = "0.10.40" 730 | source = "registry+https://github.com/rust-lang/crates.io-index" 731 | checksum = "fb81a6430ac911acb25fe5ac8f1d2af1b4ea8a4fdfda0f1ee4292af2e2d8eb0e" 732 | dependencies = [ 733 | "bitflags", 734 | "cfg-if", 735 | "foreign-types", 736 | "libc", 737 | "once_cell", 738 | "openssl-macros", 739 | "openssl-sys", 740 | ] 741 | 742 | [[package]] 743 | name = "openssl-macros" 744 | version = "0.1.0" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "b501e44f11665960c7e7fcf062c7d96a14ade4aa98116c004b2e37b5be7d736c" 747 | dependencies = [ 748 | "proc-macro2", 749 | "quote", 750 | "syn", 751 | ] 752 | 753 | [[package]] 754 | name = "openssl-sys" 755 | version = "0.9.74" 756 | source = "registry+https://github.com/rust-lang/crates.io-index" 757 | checksum = "835363342df5fba8354c5b453325b110ffd54044e588c539cf2f20a8014e4cb1" 758 | dependencies = [ 759 | "autocfg", 760 | "cc", 761 | "libc", 762 | "pkg-config", 763 | "vcpkg", 764 | ] 765 | 766 | [[package]] 767 | name = "ordered-float" 768 | version = "2.10.0" 769 | source = "registry+https://github.com/rust-lang/crates.io-index" 770 | checksum = "7940cf2ca942593318d07fcf2596cdca60a85c9e7fab408a5e21a4f9dcd40d87" 771 | dependencies = [ 772 | "num-traits 0.2.15", 773 | ] 774 | 775 | [[package]] 776 | name = "os_str_bytes" 777 | version = "6.0.0" 778 | source = "registry+https://github.com/rust-lang/crates.io-index" 779 | checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64" 780 | 781 | [[package]] 782 | name = "os_type" 783 | version = "2.4.0" 784 | source = "registry+https://github.com/rust-lang/crates.io-index" 785 | checksum = "c3df761f6470298359f84fcfb60d86db02acc22c251c37265c07a3d1057d2389" 786 | dependencies = [ 787 | "regex", 788 | ] 789 | 790 | [[package]] 791 | name = "parking_lot" 792 | version = "0.12.1" 793 | source = "registry+https://github.com/rust-lang/crates.io-index" 794 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 795 | dependencies = [ 796 | "lock_api", 797 | "parking_lot_core", 798 | ] 799 | 800 | [[package]] 801 | name = "parking_lot_core" 802 | version = "0.9.3" 803 | source = "registry+https://github.com/rust-lang/crates.io-index" 804 | checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" 805 | dependencies = [ 806 | "cfg-if", 807 | "libc", 808 | "redox_syscall", 809 | "smallvec", 810 | "windows-sys", 811 | ] 812 | 813 | [[package]] 814 | name = "petgraph" 815 | version = "0.6.2" 816 | source = "registry+https://github.com/rust-lang/crates.io-index" 817 | checksum = "e6d5014253a1331579ce62aa67443b4a658c5e7dd03d4bc6d302b94474888143" 818 | dependencies = [ 819 | "fixedbitset", 820 | "indexmap", 821 | ] 822 | 823 | [[package]] 824 | name = "pkg-config" 825 | version = "0.3.25" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "1df8c4ec4b0627e53bdf214615ad287367e482558cf84b109250b37464dc03ae" 828 | 829 | [[package]] 830 | name = "proc-macro2" 831 | version = "1.0.37" 832 | source = "registry+https://github.com/rust-lang/crates.io-index" 833 | checksum = "ec757218438d5fda206afc041538b2f6d889286160d649a86a24d37e1235afd1" 834 | dependencies = [ 835 | "unicode-xid", 836 | ] 837 | 838 | [[package]] 839 | name = "ptree" 840 | version = "0.4.0" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "a0de80796b316aec75344095a6d2ef68ec9b8f573b9e7adc821149ba3598e270" 843 | dependencies = [ 844 | "ansi_term", 845 | "atty", 846 | "config", 847 | "directories", 848 | "petgraph", 849 | "serde 1.0.136", 850 | "serde-value", 851 | "tint", 852 | ] 853 | 854 | [[package]] 855 | name = "quote" 856 | version = "1.0.18" 857 | source = "registry+https://github.com/rust-lang/crates.io-index" 858 | checksum = "a1feb54ed693b93a84e14094943b84b7c4eae204c512b7ccb95ab0c66d278ad1" 859 | dependencies = [ 860 | "proc-macro2", 861 | ] 862 | 863 | [[package]] 864 | name = "rayon" 865 | version = "1.5.2" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "fd249e82c21598a9a426a4e00dd7adc1d640b22445ec8545feef801d1a74c221" 868 | dependencies = [ 869 | "autocfg", 870 | "crossbeam-deque", 871 | "either", 872 | "rayon-core", 873 | ] 874 | 875 | [[package]] 876 | name = "rayon-core" 877 | version = "1.9.2" 878 | source = "registry+https://github.com/rust-lang/crates.io-index" 879 | checksum = "9f51245e1e62e1f1629cbfec37b5793bbabcaeb90f30e94d2ba03564687353e4" 880 | dependencies = [ 881 | "crossbeam-channel", 882 | "crossbeam-deque", 883 | "crossbeam-utils", 884 | "num_cpus", 885 | ] 886 | 887 | [[package]] 888 | name = "redox_syscall" 889 | version = "0.2.13" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 892 | dependencies = [ 893 | "bitflags", 894 | ] 895 | 896 | [[package]] 897 | name = "redox_users" 898 | version = "0.4.3" 899 | source = "registry+https://github.com/rust-lang/crates.io-index" 900 | checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" 901 | dependencies = [ 902 | "getrandom", 903 | "redox_syscall", 904 | "thiserror", 905 | ] 906 | 907 | [[package]] 908 | name = "regex" 909 | version = "1.5.5" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286" 912 | dependencies = [ 913 | "aho-corasick", 914 | "memchr", 915 | "regex-syntax", 916 | ] 917 | 918 | [[package]] 919 | name = "regex-syntax" 920 | version = "0.6.25" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" 923 | 924 | [[package]] 925 | name = "remove_dir_all" 926 | version = "0.5.3" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7" 929 | dependencies = [ 930 | "winapi", 931 | ] 932 | 933 | [[package]] 934 | name = "rust-ini" 935 | version = "0.13.0" 936 | source = "registry+https://github.com/rust-lang/crates.io-index" 937 | checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2" 938 | 939 | [[package]] 940 | name = "rustc-demangle" 941 | version = "0.1.21" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342" 944 | 945 | [[package]] 946 | name = "rustc_version" 947 | version = "0.4.0" 948 | source = "registry+https://github.com/rust-lang/crates.io-index" 949 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 950 | dependencies = [ 951 | "semver", 952 | ] 953 | 954 | [[package]] 955 | name = "rustversion" 956 | version = "1.0.6" 957 | source = "registry+https://github.com/rust-lang/crates.io-index" 958 | checksum = "f2cc38e8fa666e2de3c4aba7edeb5ffc5246c1c2ed0e3d17e560aeeba736b23f" 959 | 960 | [[package]] 961 | name = "ryu" 962 | version = "1.0.10" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" 965 | 966 | [[package]] 967 | name = "same-file" 968 | version = "1.0.6" 969 | source = "registry+https://github.com/rust-lang/crates.io-index" 970 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 971 | dependencies = [ 972 | "winapi-util", 973 | ] 974 | 975 | [[package]] 976 | name = "scopeguard" 977 | version = "1.1.0" 978 | source = "registry+https://github.com/rust-lang/crates.io-index" 979 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 980 | 981 | [[package]] 982 | name = "semver" 983 | version = "1.0.7" 984 | source = "registry+https://github.com/rust-lang/crates.io-index" 985 | checksum = "d65bd28f48be7196d222d95b9243287f48d27aca604e08497513019ff0502cc4" 986 | 987 | [[package]] 988 | name = "serde" 989 | version = "0.8.23" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8" 992 | 993 | [[package]] 994 | name = "serde" 995 | version = "1.0.136" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789" 998 | dependencies = [ 999 | "serde_derive", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "serde-hjson" 1004 | version = "0.9.1" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8" 1007 | dependencies = [ 1008 | "lazy_static 1.4.0", 1009 | "num-traits 0.1.43", 1010 | "regex", 1011 | "serde 0.8.23", 1012 | ] 1013 | 1014 | [[package]] 1015 | name = "serde-value" 1016 | version = "0.7.0" 1017 | source = "registry+https://github.com/rust-lang/crates.io-index" 1018 | checksum = "f3a1a3341211875ef120e117ea7fd5228530ae7e7036a779fdc9117be6b3282c" 1019 | dependencies = [ 1020 | "ordered-float", 1021 | "serde 1.0.136", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "serde_derive" 1026 | version = "1.0.136" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "08597e7152fcd306f41838ed3e37be9eaeed2b61c42e2117266a554fab4662f9" 1029 | dependencies = [ 1030 | "proc-macro2", 1031 | "quote", 1032 | "syn", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "serde_json" 1037 | version = "1.0.81" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "9b7ce2b32a1aed03c558dc61a5cd328f15aff2dbc17daad8fb8af04d2100e15c" 1040 | dependencies = [ 1041 | "itoa", 1042 | "ryu", 1043 | "serde 1.0.136", 1044 | ] 1045 | 1046 | [[package]] 1047 | name = "shell-escape" 1048 | version = "0.1.5" 1049 | source = "registry+https://github.com/rust-lang/crates.io-index" 1050 | checksum = "45bb67a18fa91266cc7807181f62f9178a6873bfad7dc788c42e6430db40184f" 1051 | 1052 | [[package]] 1053 | name = "signal-hook" 1054 | version = "0.3.14" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d" 1057 | dependencies = [ 1058 | "libc", 1059 | "signal-hook-registry", 1060 | ] 1061 | 1062 | [[package]] 1063 | name = "signal-hook-mio" 1064 | version = "0.2.3" 1065 | source = "registry+https://github.com/rust-lang/crates.io-index" 1066 | checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" 1067 | dependencies = [ 1068 | "libc", 1069 | "mio", 1070 | "signal-hook", 1071 | ] 1072 | 1073 | [[package]] 1074 | name = "signal-hook-registry" 1075 | version = "1.4.0" 1076 | source = "registry+https://github.com/rust-lang/crates.io-index" 1077 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 1078 | dependencies = [ 1079 | "libc", 1080 | ] 1081 | 1082 | [[package]] 1083 | name = "smallvec" 1084 | version = "1.8.0" 1085 | source = "registry+https://github.com/rust-lang/crates.io-index" 1086 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 1087 | 1088 | [[package]] 1089 | name = "static_assertions" 1090 | version = "1.1.0" 1091 | source = "registry+https://github.com/rust-lang/crates.io-index" 1092 | checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" 1093 | 1094 | [[package]] 1095 | name = "strum" 1096 | version = "0.24.0" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "e96acfc1b70604b8b2f1ffa4c57e59176c7dbb05d556c71ecd2f5498a1dee7f8" 1099 | 1100 | [[package]] 1101 | name = "strum_macros" 1102 | version = "0.24.0" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "6878079b17446e4d3eba6192bb0a2950d5b14f0ed8424b852310e5a94345d0ef" 1105 | dependencies = [ 1106 | "heck", 1107 | "proc-macro2", 1108 | "quote", 1109 | "rustversion", 1110 | "syn", 1111 | ] 1112 | 1113 | [[package]] 1114 | name = "syn" 1115 | version = "1.0.91" 1116 | source = "registry+https://github.com/rust-lang/crates.io-index" 1117 | checksum = "b683b2b825c8eef438b77c36a06dc262294da3d5a5813fac20da149241dcd44d" 1118 | dependencies = [ 1119 | "proc-macro2", 1120 | "quote", 1121 | "unicode-xid", 1122 | ] 1123 | 1124 | [[package]] 1125 | name = "sys-info" 1126 | version = "0.9.1" 1127 | source = "registry+https://github.com/rust-lang/crates.io-index" 1128 | checksum = "0b3a0d0aba8bf96a0e1ddfdc352fc53b3df7f39318c71854910c3c4b024ae52c" 1129 | dependencies = [ 1130 | "cc", 1131 | "libc", 1132 | ] 1133 | 1134 | [[package]] 1135 | name = "sysinfo" 1136 | version = "0.24.1" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | checksum = "a6a8e71535da31837213ac114531d31def75d7aebd133264e420a3451fa7f703" 1139 | dependencies = [ 1140 | "cfg-if", 1141 | "core-foundation-sys", 1142 | "libc", 1143 | "ntapi", 1144 | "once_cell", 1145 | "rayon", 1146 | "winapi", 1147 | ] 1148 | 1149 | [[package]] 1150 | name = "tempfile" 1151 | version = "3.3.0" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4" 1154 | dependencies = [ 1155 | "cfg-if", 1156 | "fastrand", 1157 | "libc", 1158 | "redox_syscall", 1159 | "remove_dir_all", 1160 | "winapi", 1161 | ] 1162 | 1163 | [[package]] 1164 | name = "termcolor" 1165 | version = "1.1.3" 1166 | source = "registry+https://github.com/rust-lang/crates.io-index" 1167 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1168 | dependencies = [ 1169 | "winapi-util", 1170 | ] 1171 | 1172 | [[package]] 1173 | name = "terminal_size" 1174 | version = "0.1.17" 1175 | source = "registry+https://github.com/rust-lang/crates.io-index" 1176 | checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df" 1177 | dependencies = [ 1178 | "libc", 1179 | "winapi", 1180 | ] 1181 | 1182 | [[package]] 1183 | name = "textwrap" 1184 | version = "0.15.0" 1185 | source = "registry+https://github.com/rust-lang/crates.io-index" 1186 | checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" 1187 | 1188 | [[package]] 1189 | name = "thiserror" 1190 | version = "1.0.30" 1191 | source = "registry+https://github.com/rust-lang/crates.io-index" 1192 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" 1193 | dependencies = [ 1194 | "thiserror-impl", 1195 | ] 1196 | 1197 | [[package]] 1198 | name = "thiserror-impl" 1199 | version = "1.0.30" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" 1202 | dependencies = [ 1203 | "proc-macro2", 1204 | "quote", 1205 | "syn", 1206 | ] 1207 | 1208 | [[package]] 1209 | name = "tint" 1210 | version = "1.0.1" 1211 | source = "registry+https://github.com/rust-lang/crates.io-index" 1212 | checksum = "7af24570664a3074673dbbf69a65bdae0ae0b72f2949b1adfbacb736ee4d6896" 1213 | dependencies = [ 1214 | "lazy_static 0.2.11", 1215 | ] 1216 | 1217 | [[package]] 1218 | name = "toml" 1219 | version = "0.5.8" 1220 | source = "registry+https://github.com/rust-lang/crates.io-index" 1221 | checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" 1222 | dependencies = [ 1223 | "indexmap", 1224 | "serde 1.0.136", 1225 | ] 1226 | 1227 | [[package]] 1228 | name = "unicode-width" 1229 | version = "0.1.9" 1230 | source = "registry+https://github.com/rust-lang/crates.io-index" 1231 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" 1232 | 1233 | [[package]] 1234 | name = "unicode-xid" 1235 | version = "0.2.2" 1236 | source = "registry+https://github.com/rust-lang/crates.io-index" 1237 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" 1238 | 1239 | [[package]] 1240 | name = "utf8-width" 1241 | version = "0.1.6" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "5190c9442dcdaf0ddd50f37420417d219ae5261bbf5db120d0f9bab996c9cba1" 1244 | 1245 | [[package]] 1246 | name = "uuid" 1247 | version = "0.8.2" 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" 1249 | checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" 1250 | dependencies = [ 1251 | "getrandom", 1252 | ] 1253 | 1254 | [[package]] 1255 | name = "uuid" 1256 | version = "1.0.0" 1257 | source = "registry+https://github.com/rust-lang/crates.io-index" 1258 | checksum = "8cfcd319456c4d6ea10087ed423473267e1a071f3bc0aa89f80d60997843c6f0" 1259 | dependencies = [ 1260 | "getrandom", 1261 | "serde 1.0.136", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "vcpkg" 1266 | version = "0.2.15" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 1269 | 1270 | [[package]] 1271 | name = "version_check" 1272 | version = "0.9.4" 1273 | source = "registry+https://github.com/rust-lang/crates.io-index" 1274 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1275 | 1276 | [[package]] 1277 | name = "walkdir" 1278 | version = "2.3.2" 1279 | source = "registry+https://github.com/rust-lang/crates.io-index" 1280 | checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" 1281 | dependencies = [ 1282 | "same-file", 1283 | "winapi", 1284 | "winapi-util", 1285 | ] 1286 | 1287 | [[package]] 1288 | name = "wasi" 1289 | version = "0.10.2+wasi-snapshot-preview1" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" 1292 | 1293 | [[package]] 1294 | name = "wasi" 1295 | version = "0.11.0+wasi-snapshot-preview1" 1296 | source = "registry+https://github.com/rust-lang/crates.io-index" 1297 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1298 | 1299 | [[package]] 1300 | name = "which" 1301 | version = "4.2.5" 1302 | source = "registry+https://github.com/rust-lang/crates.io-index" 1303 | checksum = "5c4fb54e6113b6a8772ee41c3404fb0301ac79604489467e0a9ce1f3e97c24ae" 1304 | dependencies = [ 1305 | "either", 1306 | "lazy_static 1.4.0", 1307 | "libc", 1308 | ] 1309 | 1310 | [[package]] 1311 | name = "winapi" 1312 | version = "0.3.9" 1313 | source = "registry+https://github.com/rust-lang/crates.io-index" 1314 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1315 | dependencies = [ 1316 | "winapi-i686-pc-windows-gnu", 1317 | "winapi-x86_64-pc-windows-gnu", 1318 | ] 1319 | 1320 | [[package]] 1321 | name = "winapi-i686-pc-windows-gnu" 1322 | version = "0.4.0" 1323 | source = "registry+https://github.com/rust-lang/crates.io-index" 1324 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1325 | 1326 | [[package]] 1327 | name = "winapi-util" 1328 | version = "0.1.5" 1329 | source = "registry+https://github.com/rust-lang/crates.io-index" 1330 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1331 | dependencies = [ 1332 | "winapi", 1333 | ] 1334 | 1335 | [[package]] 1336 | name = "winapi-x86_64-pc-windows-gnu" 1337 | version = "0.4.0" 1338 | source = "registry+https://github.com/rust-lang/crates.io-index" 1339 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1340 | 1341 | [[package]] 1342 | name = "windows-sys" 1343 | version = "0.36.1" 1344 | source = "registry+https://github.com/rust-lang/crates.io-index" 1345 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1346 | dependencies = [ 1347 | "windows_aarch64_msvc", 1348 | "windows_i686_gnu", 1349 | "windows_i686_msvc", 1350 | "windows_x86_64_gnu", 1351 | "windows_x86_64_msvc", 1352 | ] 1353 | 1354 | [[package]] 1355 | name = "windows_aarch64_msvc" 1356 | version = "0.36.1" 1357 | source = "registry+https://github.com/rust-lang/crates.io-index" 1358 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1359 | 1360 | [[package]] 1361 | name = "windows_i686_gnu" 1362 | version = "0.36.1" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1365 | 1366 | [[package]] 1367 | name = "windows_i686_msvc" 1368 | version = "0.36.1" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1371 | 1372 | [[package]] 1373 | name = "windows_x86_64_gnu" 1374 | version = "0.36.1" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1377 | 1378 | [[package]] 1379 | name = "windows_x86_64_msvc" 1380 | version = "0.36.1" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1383 | 1384 | [[package]] 1385 | name = "wsl" 1386 | version = "0.1.0" 1387 | source = "registry+https://github.com/rust-lang/crates.io-index" 1388 | checksum = "f8dab7ac864710bdea6594becbea5b5050333cf34fefb0dc319567eb347950d4" 1389 | 1390 | [[package]] 1391 | name = "yaml-rust" 1392 | version = "0.4.5" 1393 | source = "registry+https://github.com/rust-lang/crates.io-index" 1394 | checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" 1395 | dependencies = [ 1396 | "linked-hash-map", 1397 | ] 1398 | 1399 | [[package]] 1400 | name = "zeroize" 1401 | version = "1.5.4" 1402 | source = "registry+https://github.com/rust-lang/crates.io-index" 1403 | checksum = "7eb5728b8afd3f280a869ce1d4c554ffaed35f45c231fc41bfbd0381bef50317" 1404 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "fleet-rs" 3 | version = "0.0.8" 4 | edition = "2021" 5 | description = "The blazing fast build tool for Rust." 6 | authors = ["Dimension "] 7 | license = "Apache-2.0" 8 | readme = "README.md" 9 | homepage = "https://fleet.rs" 10 | repository = "https://github.com/dimensionhq/fleet" 11 | keywords = ["rust", "build", "tool"] 12 | categories = ["build", "rust-build-tools"] 13 | 14 | [[bin]] 15 | name = "cargo-fleet" 16 | path = "src/main.rs" 17 | 18 | [[bin]] 19 | name = "fleet" 20 | path = "src/../src/main.rs" 21 | test = false 22 | bench = false 23 | 24 | [build-dependencies] 25 | rustc_version = "0.4.0" 26 | 27 | [dependencies] 28 | anyhow = "1.0.57" 29 | ansi_term = "0.12" 30 | dirs = "4.0.0" 31 | wsl = "0.1.0" 32 | sysinfo = "0.24.1" 33 | rustc_version = "0.4.0" 34 | dialoguer = "0.10.0" 35 | colored = "2.0.0" 36 | sys-info = "0.9.1" 37 | which = "4.2.5" 38 | serde_json = "1.0.81" 39 | comfy-table = "6.0.0" 40 | byte-unit = "4.0.14" 41 | cargo-util = "0.1.2" 42 | indicatif = "0.16.2" 43 | human-panic = "1.0.3" 44 | ptree = "0.4.0" 45 | 46 | [dependencies.clap] 47 | version = "3.1.18" 48 | features = ["cargo", "std", "color"] 49 | default-features = false 50 | 51 | [dependencies.serde] 52 | version = "1.0" 53 | features = ["derive"] 54 | 55 | [dependencies.toml] 56 | version = "0.5.8" 57 | features = ["preserve_order"] 58 | 59 | [dependencies.uuid] 60 | version = "1.0.0" 61 | features = ["serde", "v4"] 62 | 63 | [profile.dev] 64 | opt-level = 0 65 | debug = 2 66 | incremental = true 67 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 30 | 31 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 32 | 33 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 34 | 35 | You must give any other recipients of the Work or Derivative Works a copy of this License; and 36 | You must cause any modified files to carry prominent notices stating that You changed the files; and 37 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 38 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 39 | 40 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 41 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 42 | 43 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 44 | 45 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 46 | 47 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 48 | 49 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 50 | 51 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![image](https://user-images.githubusercontent.com/63039748/164709140-8bb96d45-972e-4ac5-8e0e-ae566e673761.png) 2 | 3 |

4 | 5 |

6 | 7 |
8 | 9 | 10 | [Fleet](https://fleet.rs) is a blazing fast build tool for Rust. Compiling with Fleet is up-to 5x faster than with `cargo`. 11 | 12 | **Note**: Since Fleet is still under development, it might not be completely stable yet. Feel free to open any issues or bug reports at [issues](https://github.com/dimensionhq/fleet/issues/). 13 | 14 |
15 | 16 | # :zap: Installation 17 | 18 | On MacOS & Linux: 19 | ```bash 20 | curl -L get.fleet.rs | sh 21 | ``` 22 |
23 | 24 | On Windows: 25 | ```powershell 26 | iwr -useb windows.fleet.rs | iex 27 | ``` 28 | 29 | ## Building from source 30 | Prerequisites: **Rust** 31 | ```powershell 32 | cargo install --git https://github.com/dimensionhq/fleet fleet-rs 33 | ``` 34 | 35 | 36 | ## How does fleet work? 37 | 38 | Fleet works by optimizing your builds using existing tooling available in the Rust ecosystem, including seamlessly integrating sccache, lld, zld, ramdisks (for those using WSL or HDD's) et al. 39 | 40 | ## Versioning 41 | 42 | We use [SemVer](http://semver.org/) for versioning. For the versions available, see the [tags on this repository](https://github.com/dimensionhq/fleet/tags). 43 | 44 | ## License 45 | 46 | This project is licensed under the Apache 2.0 License - see the [LICENSE.md](LICENSE) file for details. 47 | -------------------------------------------------------------------------------- /fleet.toml: -------------------------------------------------------------------------------- 1 | rd_enabled = true 2 | fleet_id = "eec7a0b5-3138-4bf6-989b-7e49c41c3e29" 3 | 4 | [build] 5 | -------------------------------------------------------------------------------- /installer/.cargo/config.toml: -------------------------------------------------------------------------------- 1 | [profile.release] 2 | strip="debuginfo" 3 | -------------------------------------------------------------------------------- /installer/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 = "enable-ansi-support" 7 | version = "0.1.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "28d29d3ca9ba14c336417f8d7bc7f373e8c16d10c30cc0794b09d3cecab631ab" 10 | dependencies = [ 11 | "winapi", 12 | ] 13 | 14 | [[package]] 15 | name = "installer" 16 | version = "0.1.0" 17 | dependencies = [ 18 | "enable-ansi-support", 19 | "owo-colors", 20 | ] 21 | 22 | [[package]] 23 | name = "owo-colors" 24 | version = "3.3.0" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "5e72e30578e0d0993c8ae20823dd9cff2bc5517d2f586a8aef462a581e8a03eb" 27 | 28 | [[package]] 29 | name = "winapi" 30 | version = "0.3.9" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 33 | dependencies = [ 34 | "winapi-i686-pc-windows-gnu", 35 | "winapi-x86_64-pc-windows-gnu", 36 | ] 37 | 38 | [[package]] 39 | name = "winapi-i686-pc-windows-gnu" 40 | version = "0.4.0" 41 | source = "registry+https://github.com/rust-lang/crates.io-index" 42 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 43 | 44 | [[package]] 45 | name = "winapi-x86_64-pc-windows-gnu" 46 | version = "0.4.0" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 49 | -------------------------------------------------------------------------------- /installer/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "installer" 3 | version = "0.1.0" 4 | edition = "2021" 5 | 6 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 7 | 8 | [dependencies] 9 | owo-colors = "3.3.0" 10 | enable-ansi-support = "0.1.2" 11 | -------------------------------------------------------------------------------- /installer/LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. 10 | 11 | "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. 12 | 13 | "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. 14 | 15 | "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. 16 | 17 | "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. 18 | 19 | "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. 20 | 21 | "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). 22 | 23 | "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 24 | 25 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." 26 | 27 | "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 28 | 29 | 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 30 | 31 | 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 32 | 33 | 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: 34 | 35 | You must give any other recipients of the Work or Derivative Works a copy of this License; and 36 | You must cause any modified files to carry prominent notices stating that You changed the files; and 37 | You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and 38 | If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. 39 | 40 | You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 41 | 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 42 | 43 | 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 44 | 45 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 46 | 47 | 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 48 | 49 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. 50 | 51 | END OF TERMS AND CONDITIONS -------------------------------------------------------------------------------- /installer/fleet.toml: -------------------------------------------------------------------------------- 1 | rd_enabled = true 2 | fleet_id = "c3e72e77-71d5-4b60-b849-972f237efe9b" 3 | 4 | [build] 5 | sccache = "/Users/xtremedevx/.cargo/bin/sccache" 6 | -------------------------------------------------------------------------------- /installer/install.sh: -------------------------------------------------------------------------------- 1 | echo Downloading Fleet installer... 2 | 3 | # Download the installer 4 | if [[ "$OSTYPE" =~ ^darwin ]]; then 5 | curl https://cdn.dimension.dev/dimension/fleet/bin/installer-macos.bin -o installer.bin 6 | fi 7 | 8 | if [[ "$OSTYPE" =~ ^linux ]]; then 9 | curl https://cdn.dimension.dev/dimension/fleet/bin/installer-linux.bin -o installer.bin 10 | fi 11 | 12 | # Make it an executable 13 | chmod +x installer.bin 14 | # Run the installer 15 | ./installer.bin 16 | -------------------------------------------------------------------------------- /installer/src/main.rs: -------------------------------------------------------------------------------- 1 | use owo_colors::OwoColorize; 2 | use std::process::Command; 3 | 4 | pub fn install_sccache() { 5 | println!("{}", "> cargo install sccache".bright_cyan()); 6 | 7 | // Install sccache 8 | let status = Command::new("cargo") 9 | .arg("install") 10 | .arg("sccache") 11 | .arg("-f") 12 | .status() 13 | .unwrap(); 14 | 15 | if status.success() { 16 | println!("{}", "Installed SCCache".bright_green()); 17 | } else { 18 | println!("{}", "Failed to install SCCache".bright_red()); 19 | } 20 | } 21 | 22 | pub fn set_compiler_nightly() { 23 | println!("{}", "> rustup default nightly".bright_cyan()); 24 | 25 | // Set nightly compiler 26 | let status = Command::new("rustup") 27 | .arg("default") 28 | .arg("nightly") 29 | .status() 30 | .unwrap(); 31 | 32 | if status.success() { 33 | println!( 34 | "{} {} {}", 35 | "Switched to".bright_green(), 36 | "nightly".bright_blue(), 37 | "compiler".bright_green(), 38 | ); 39 | } else { 40 | println!("{}", "Failed to set nightly compiler".bright_red()); 41 | } 42 | } 43 | 44 | pub fn install_fleet() { 45 | println!("{}", "> cargo install fleet-rs".bright_cyan()); 46 | 47 | // Install Fleet 48 | let status = Command::new("cargo") 49 | .arg("install") 50 | .arg("fleet-rs") 51 | .arg("-f") 52 | .status() 53 | .unwrap(); 54 | 55 | if status.success() { 56 | println!("{}", "Installed Fleet".bright_green()); 57 | } else { 58 | println!("{}", "Failed to install Fleet".bright_red()); 59 | } 60 | } 61 | 62 | fn main() { 63 | println!("🚀 Installing Fleet"); 64 | 65 | match std::env::consts::OS { 66 | "macos" => { 67 | println!("💻 Installing for MacOS"); 68 | 69 | println!( 70 | "{}", 71 | format!( 72 | "{} {} {} {} ", 73 | "Please ensure you have the following packages installed:", 74 | "zld\n".bright_cyan(), 75 | "brew:", 76 | "brew install michaeleisel/zld/zld".bright_yellow() 77 | ) 78 | ); 79 | 80 | set_compiler_nightly(); 81 | install_sccache(); 82 | install_fleet(); 83 | 84 | println!("{}", "Installation complete".bright_green()); 85 | } 86 | "linux" => { 87 | println!("💻 Installing for Linux"); 88 | 89 | println!( 90 | "{}", 91 | format!( 92 | "{} {} {} {} {} {}", 93 | "Please ensure you have the following packages installed:", 94 | "lld, clang\n".bright_cyan(), 95 | "Pacman:", 96 | "sudo pacman -S clang lld\n".bright_yellow(), 97 | "Apt:", 98 | "sudo apt install clang lld".bright_yellow() 99 | ) 100 | ); 101 | 102 | set_compiler_nightly(); 103 | install_sccache(); 104 | install_fleet(); 105 | 106 | println!("{}", "Installation complete".bright_green()); 107 | } 108 | "windows" => { 109 | println!("💻 Installing for Windows"); 110 | 111 | let _ = enable_ansi_support::enable_ansi_support(); 112 | 113 | set_compiler_nightly(); 114 | install_sccache(); 115 | install_fleet(); 116 | 117 | println!("{}", "Installation complete".bright_green()); 118 | } 119 | _ => { 120 | println!("OS Not Supported"); 121 | } 122 | } 123 | } 124 | -------------------------------------------------------------------------------- /src/cli/app.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::core::config::FleetConfig; 19 | use clap::{ 20 | arg, crate_authors, crate_description, crate_name, crate_version, Command as CliCommand, Values, 21 | }; 22 | use colored::Colorize; 23 | use std::{env::current_dir, path::PathBuf}; 24 | 25 | use crate::cli::help; 26 | use crate::core::commands::{bloat, build, configure, init, run, udeps}; 27 | use anyhow::Result; 28 | use std::process::{self, exit}; 29 | 30 | pub enum Command { 31 | Init(Option>), 32 | Build(Option>), 33 | Run(Option>), 34 | Bloat(Option>), 35 | Configure(Option>), 36 | Udeps(Option>), 37 | } 38 | 39 | pub struct App { 40 | pub config: FleetConfig, 41 | pub current_dir: PathBuf, 42 | } 43 | 44 | impl Default for App { 45 | fn default() -> Self { 46 | Self::new() 47 | } 48 | } 49 | 50 | impl App { 51 | ///Creates a new app 52 | /// 53 | /// # Panics 54 | /// Can panic if current directory is not found (eg. doesn't exist or invalid perms) 55 | #[must_use] 56 | pub fn new() -> Self { 57 | let current_dir = current_dir().expect("Unable to find current directory for app!"); 58 | 59 | Self { 60 | config: FleetConfig::run_config(), 61 | current_dir, 62 | } 63 | } 64 | 65 | fn build<'a>(&self) -> CliCommand<'a> { 66 | CliCommand::new(crate_name!()) 67 | .version(crate_version!()) 68 | .about(crate_description!()) 69 | .author(crate_authors!()) 70 | .arg( 71 | arg!(-c --command ) 72 | .required(false) 73 | .default_missing_value(""), 74 | ) 75 | .subcommand( 76 | CliCommand::new("init") 77 | .about("Initialize a fleet project") 78 | .arg(arg!([EXTRA]).multiple_values(true)), 79 | ) 80 | .subcommand( 81 | CliCommand::new("run") 82 | .about("Runs the fleet project") 83 | .arg(arg!([EXTRA]).multiple_values(true)), 84 | ) 85 | .subcommand( 86 | CliCommand::new("build") 87 | .about("Builds a fleet project") 88 | .arg(arg!([EXTRA]).multiple_values(true)), 89 | ) 90 | .subcommand(CliCommand::new("configure").about("Configure a fleet project")) 91 | .subcommand(CliCommand::new("bloat").about("?")) 92 | .subcommand(CliCommand::new("udeps").about("?")) 93 | } 94 | 95 | fn get_command(&self) -> Command { 96 | let mut options = self.build(); 97 | 98 | // There should be a better way to implement this 99 | let matches = Box::leak(options.clone().get_matches().into()); 100 | 101 | match matches.value_of("command") { 102 | Some(cmd) => { 103 | match cmd { 104 | "run" => { 105 | println!("{}", help::run_help()) 106 | } 107 | "build" => { 108 | println!("{}", help::build_help()) 109 | } 110 | _ => options.print_help().unwrap(), 111 | } 112 | 113 | process::exit(1) 114 | } 115 | None => {} 116 | } 117 | 118 | match matches.subcommand() { 119 | Some(("init", _sub)) => Command::Init(None), 120 | Some(("build", sub)) => Command::Build(sub.values_of("EXTRA")), 121 | Some(("run", sub)) => Command::Run(sub.values_of("EXTRA")), 122 | Some(("bloat", _sub)) => Command::Bloat(None), 123 | Some(("udeps", _sub)) => Command::Udeps(None), 124 | Some(("configure", _sub)) => Command::Configure(None), 125 | _ => { 126 | options.print_help().unwrap_or_else(|_| { 127 | eprintln!("{}", "Failed to display help.".red(),); 128 | exit(1); 129 | }); 130 | exit(0) 131 | } 132 | } 133 | } 134 | 135 | pub fn run(self) -> Result<()> { 136 | let command = self.get_command(); 137 | 138 | match command { 139 | Command::Init(args) => init::run(self, args), 140 | Command::Build(args) => build::run(self, args), 141 | Command::Run(args) => run::run(self, args), 142 | Command::Bloat(args) => bloat::run(self, args), 143 | Command::Configure(args) => configure::run(self, args), 144 | Command::Udeps(args) => udeps::run(self, args), 145 | } 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/cli/help.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use colored::Colorize; 19 | 20 | pub fn build_help() -> String { 21 | format!( 22 | r#"{} {} 23 | Dimension 24 | The blazing fast build tool for Rust. 25 | 26 | {}: 27 | fleet build [OPTIONS] 28 | 29 | {}: 30 | -q, --quiet Do not print cargo log messages 31 | -p, --package [] Package to build (see `cargo help pkgid`) 32 | --workspace Build all packages in the workspace 33 | --exclude Exclude packages from the build 34 | -v, --verbose Use verbose output (-vv very verbose/build.rs output) 35 | --all Alias for --workspace (deprecated) 36 | --color Coloring: auto, always, never 37 | -j, --jobs Number of parallel jobs, defaults to # of CPUs 38 | --frozen Require Cargo.lock and cache are up to date 39 | --keep-going Do not abort the build as soon as there is an error (unstable) 40 | --lib Build only this package's library 41 | --locked Require Cargo.lock is up to date 42 | --bin [] Build only the specified binary 43 | --offline Run without accessing the network 44 | --bins Build all binaries 45 | --config Override a configuration value (unstable) 46 | --example [] Build only the specified example 47 | -Z Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for 48 | details 49 | --examples Build all examples 50 | --test [] Build only the specified test target 51 | --tests Build all tests 52 | --bench [] Build only the specified bench target 53 | --benches Build all benches 54 | --all-targets Build all targets 55 | -r, --release Build artifacts in release mode, with optimizations 56 | --profile Build artifacts with the specified profile 57 | --features Space or comma separated list of features to activate 58 | --all-features Activate all available features 59 | --no-default-features Do not activate the `default` feature 60 | --target Build for the target triple 61 | --target-dir Directory for all generated artifacts 62 | --out-dir Copy final artifacts to this directory (unstable) 63 | --manifest-path Path to Cargo.toml 64 | --ignore-rust-version Ignore `rust-version` specification in packages 65 | --message-format Error format 66 | --build-plan Output the build plan in JSON (unstable) 67 | --unit-graph Output build graph in JSON (unstable) 68 | --future-incompat-report Outputs a future incompatibility report at the end of the build 69 | --timings[=...] Timing output formats (unstable) (comma separated): html, json 70 | -h, --help Print help information 71 | "#, 72 | "fleet".green(), 73 | env!("CARGO_PKG_VERSION").green(), 74 | "USAGE".yellow(), 75 | "OPTIONS".yellow() 76 | ) 77 | } 78 | 79 | pub fn run_help() -> String { 80 | format!( 81 | r#"{} {} 82 | Dimension 83 | The blazing fast build tool for Rust. 84 | 85 | {}: 86 | fleet run [OPTIONS] 87 | 88 | {}: 89 | -q, --quiet Do not print cargo log messages 90 | --bin [] Name of the bin target to run 91 | --example [] Name of the example target to run 92 | -p, --package [...] Package with the target to run 93 | -v, --verbose Use verbose output (-vv very verbose/build.rs output) 94 | -j, --jobs Number of parallel jobs, defaults to # of CPUs 95 | --color Coloring: auto, always, never 96 | --keep-going Do not abort the build as soon as there is an error (unstable) 97 | --frozen Require Cargo.lock and cache are up to date 98 | -r, --release Build artifacts in release mode, with optimizations 99 | --locked Require Cargo.lock is up to date 100 | --profile Build artifacts with the specified profile 101 | --features Space or comma separated list of features to activate 102 | --offline Run without accessing the network 103 | --all-features Activate all available features 104 | --config Override a configuration value (unstable) 105 | --no-default-features Do not activate the `default` feature 106 | -Z Unstable (nightly-only) flags to Cargo, see 'cargo -Z help' for 107 | details 108 | --target Build for the target triple 109 | --target-dir Directory for all generated artifacts 110 | --manifest-path Path to Cargo.toml 111 | --message-format Error format 112 | --unit-graph Output build graph in JSON (unstable) 113 | --ignore-rust-version Ignore `rust-version` specification in packages 114 | --timings[=...] Timing output formats (unstable) (comma separated): html, json 115 | -h, --help Print help information 116 | "#, 117 | "fleet".green(), 118 | env!("CARGO_PKG_VERSION").green(), 119 | "USAGE".yellow(), 120 | "OPTIONS".yellow() 121 | ) 122 | } 123 | -------------------------------------------------------------------------------- /src/cli/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod app; 19 | pub mod help; 20 | pub mod prompt; -------------------------------------------------------------------------------- /src/cli/prompt/input.rs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Volt Contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | #![allow(dead_code)] 18 | 19 | use dialoguer::{ 20 | console::{Key, Term}, 21 | theme::{SimpleTheme, Theme}, 22 | }; 23 | 24 | use std::{ 25 | borrow::Cow, 26 | fmt::{self, Debug, Display}, 27 | io, iter, 28 | str::FromStr, 29 | }; 30 | 31 | pub(crate) struct TermThemeRenderer<'a> { 32 | term: &'a Term, 33 | theme: &'a dyn Theme, 34 | height: usize, 35 | prompt_height: usize, 36 | prompts_reset_height: bool, 37 | } 38 | 39 | impl<'a> TermThemeRenderer<'a> { 40 | pub fn new(term: &'a Term, theme: &'a dyn Theme) -> TermThemeRenderer<'a> { 41 | TermThemeRenderer { 42 | term, 43 | theme, 44 | height: 0, 45 | prompt_height: 0, 46 | prompts_reset_height: true, 47 | } 48 | } 49 | 50 | pub fn set_prompts_reset_height(&mut self, val: bool) { 51 | self.prompts_reset_height = val; 52 | } 53 | 54 | pub fn term(&self) -> &Term { 55 | self.term 56 | } 57 | 58 | pub fn add_line(&mut self) { 59 | self.height += 1; 60 | } 61 | 62 | fn write_formatted_str< 63 | F: FnOnce(&mut TermThemeRenderer<'_>, &mut dyn fmt::Write) -> fmt::Result, 64 | >( 65 | &mut self, 66 | f: F, 67 | ) -> io::Result<()> { 68 | let mut buf = String::new(); 69 | f(self, &mut buf).map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; 70 | self.height += buf.chars().filter(|&x| x == '\n').count(); 71 | self.term.write_str(&buf) 72 | } 73 | 74 | fn write_formatted_line< 75 | F: FnOnce(&mut TermThemeRenderer<'_>, &mut dyn fmt::Write) -> fmt::Result, 76 | >( 77 | &mut self, 78 | f: F, 79 | ) -> io::Result<()> { 80 | let mut buf = String::new(); 81 | f(self, &mut buf).map_err(|err| io::Error::new(io::ErrorKind::Other, err))?; 82 | self.height += buf.chars().filter(|&x| x == '\n').count() + 1; 83 | self.term.write_line(&buf) 84 | } 85 | 86 | fn write_formatted_prompt< 87 | F: FnOnce(&mut TermThemeRenderer<'_>, &mut dyn fmt::Write) -> fmt::Result, 88 | >( 89 | &mut self, 90 | f: F, 91 | ) -> io::Result<()> { 92 | self.write_formatted_line(f)?; 93 | if self.prompts_reset_height { 94 | self.prompt_height = self.height; 95 | self.height = 0; 96 | } 97 | Ok(()) 98 | } 99 | 100 | pub fn error(&mut self, err: &str) -> io::Result<()> { 101 | self.write_formatted_line(|this, buf| this.theme.format_error(buf, err)) 102 | } 103 | 104 | pub fn confirm_prompt(&mut self, prompt: &str, default: Option) -> io::Result<()> { 105 | self.write_formatted_str(|this, buf| this.theme.format_confirm_prompt(buf, prompt, default)) 106 | } 107 | 108 | pub fn confirm_prompt_selection(&mut self, prompt: &str, sel: Option) -> io::Result<()> { 109 | self.write_formatted_prompt(|this, buf| { 110 | this.theme.format_confirm_prompt_selection(buf, prompt, sel) 111 | }) 112 | } 113 | 114 | pub fn input_prompt(&mut self, prompt: &str, default: Option<&str>) -> io::Result<()> { 115 | self.write_formatted_str(|this, buf| this.theme.format_input_prompt(buf, prompt, default)) 116 | } 117 | 118 | pub fn input_prompt_selection(&mut self, prompt: &str, sel: &str) -> io::Result<()> { 119 | self.write_formatted_prompt(|this, buf| { 120 | this.theme.format_input_prompt_selection(buf, prompt, sel) 121 | }) 122 | } 123 | 124 | pub fn password_prompt(&mut self, prompt: &str) -> io::Result<()> { 125 | self.write_formatted_str(|this, buf| { 126 | write!(buf, "\r")?; 127 | this.theme.format_password_prompt(buf, prompt) 128 | }) 129 | } 130 | 131 | pub fn password_prompt_selection(&mut self, prompt: &str) -> io::Result<()> { 132 | self.write_formatted_prompt(|this, buf| { 133 | this.theme.format_password_prompt_selection(buf, prompt) 134 | }) 135 | } 136 | 137 | pub fn select_prompt(&mut self, prompt: &str) -> io::Result<()> { 138 | self.write_formatted_prompt(|this, buf| this.theme.format_select_prompt(buf, prompt)) 139 | } 140 | 141 | pub fn select_prompt_selection(&mut self, prompt: &str, sel: &str) -> io::Result<()> { 142 | self.write_formatted_prompt(|this, buf| { 143 | this.theme.format_select_prompt_selection(buf, prompt, sel) 144 | }) 145 | } 146 | 147 | pub fn select_prompt_item(&mut self, text: &str, active: bool) -> io::Result<()> { 148 | self.write_formatted_line(|this, buf| { 149 | this.theme.format_select_prompt_item(buf, text, active) 150 | }) 151 | } 152 | 153 | pub fn multi_select_prompt(&mut self, prompt: &str) -> io::Result<()> { 154 | self.write_formatted_prompt(|this, buf| this.theme.format_multi_select_prompt(buf, prompt)) 155 | } 156 | 157 | pub fn multi_select_prompt_selection(&mut self, prompt: &str, sel: &[&str]) -> io::Result<()> { 158 | self.write_formatted_prompt(|this, buf| { 159 | this.theme 160 | .format_multi_select_prompt_selection(buf, prompt, sel) 161 | }) 162 | } 163 | 164 | pub fn multi_select_prompt_item( 165 | &mut self, 166 | text: &str, 167 | checked: bool, 168 | active: bool, 169 | ) -> io::Result<()> { 170 | self.write_formatted_line(|this, buf| { 171 | this.theme 172 | .format_multi_select_prompt_item(buf, text, checked, active) 173 | }) 174 | } 175 | 176 | pub fn sort_prompt(&mut self, prompt: &str) -> io::Result<()> { 177 | self.write_formatted_prompt(|this, buf| this.theme.format_sort_prompt(buf, prompt)) 178 | } 179 | 180 | pub fn sort_prompt_selection(&mut self, prompt: &str, sel: &[&str]) -> io::Result<()> { 181 | self.write_formatted_prompt(|this, buf| { 182 | this.theme.format_sort_prompt_selection(buf, prompt, sel) 183 | }) 184 | } 185 | 186 | pub fn sort_prompt_item(&mut self, text: &str, picked: bool, active: bool) -> io::Result<()> { 187 | self.write_formatted_line(|this, buf| { 188 | this.theme 189 | .format_sort_prompt_item(buf, text, picked, active) 190 | }) 191 | } 192 | 193 | pub fn clear(&mut self) -> io::Result<()> { 194 | self.term 195 | .clear_last_lines(self.height + self.prompt_height)?; 196 | self.height = 0; 197 | Ok(()) 198 | } 199 | 200 | pub fn clear_preserve_prompt(&mut self, size_vec: &[usize]) -> io::Result<()> { 201 | let mut new_height = self.height; 202 | //Check each item size, increment on finding an overflow 203 | for size in size_vec { 204 | if *size > self.term.size().1 as usize { 205 | new_height += 1; 206 | } 207 | } 208 | self.term.clear_last_lines(new_height)?; 209 | self.height = 0; 210 | Ok(()) 211 | } 212 | } 213 | 214 | pub trait Validator { 215 | type Err: Debug + Display; 216 | 217 | /// Invoked with the value to validate. 218 | /// 219 | /// If this produces `Ok(())` then the value is used and parsed, if 220 | /// an error is returned validation fails with that error. 221 | fn validate(&mut self, input: &T) -> Result<(), Self::Err>; 222 | } 223 | 224 | impl Result<(), E>, E: Debug + Display> Validator for F { 225 | type Err = E; 226 | 227 | fn validate(&mut self, input: &T) -> Result<(), Self::Err> { 228 | self(input) 229 | } 230 | } 231 | 232 | pub struct Input<'a, T> { 233 | prompt: Cow<'a, str>, 234 | default: Option, 235 | show_default: bool, 236 | initial_text: Option>, 237 | theme: &'a dyn Theme, 238 | permit_empty: bool, 239 | validator: Option>, 240 | } 241 | 242 | pub type ValidatorFn<'a, T> = Box Option> + 'a>; 243 | 244 | impl<'a, T> Default for Input<'a, T> 245 | where 246 | T: Clone + FromStr + Display, 247 | T::Err: Display + Debug, 248 | { 249 | fn default() -> Input<'a, T> { 250 | Input::new() 251 | } 252 | } 253 | 254 | impl<'a, T> Input<'a, T> 255 | where 256 | T: Clone + FromStr + Display, 257 | T::Err: Display + Debug, 258 | { 259 | /// Creates an input prompt. 260 | #[must_use] 261 | pub fn new() -> Input<'a, T> { 262 | Input::with_theme(&SimpleTheme) 263 | } 264 | 265 | /// Creates an input prompt with a specific theme. 266 | pub fn with_theme(theme: &'a dyn Theme) -> Input<'a, T> { 267 | Input { 268 | prompt: "".into(), 269 | default: None, 270 | show_default: true, 271 | initial_text: None, 272 | theme, 273 | permit_empty: false, 274 | validator: None, 275 | } 276 | } 277 | 278 | /// Sets the input prompt. 279 | pub fn with_prompt>>(&mut self, prompt: S) -> &mut Input<'a, T> { 280 | self.prompt = prompt.into(); 281 | self 282 | } 283 | 284 | /// Sets initial text that user can accept or erase. 285 | pub fn with_initial_text>>(&mut self, val: S) -> &mut Input<'a, T> { 286 | self.initial_text = Some(val.into()); 287 | self 288 | } 289 | 290 | /// Sets a default. 291 | /// 292 | /// Out of the box the prompt does not have a default and will continue 293 | /// to display until the user inputs something and hits enter. If a default is set the user 294 | /// can instead accept the default with enter. 295 | pub fn default(&mut self, value: T) -> &mut Input<'a, T> { 296 | self.default = Some(value); 297 | self 298 | } 299 | 300 | /// Enables or disables an empty input 301 | /// 302 | /// By default, if there is no default value set for the input, the user must input a non-empty string. 303 | pub fn allow_empty(&mut self, val: bool) -> &mut Input<'a, T> { 304 | self.permit_empty = val; 305 | self 306 | } 307 | 308 | /// Disables or enables the default value display. 309 | /// 310 | /// The default behaviour is to append [`Self::default`] to the prompt to tell the 311 | /// user what is the default value. 312 | /// 313 | /// This method does not affect existance of default value, only its display in the prompt! 314 | pub fn show_default(&mut self, val: bool) -> &mut Input<'a, T> { 315 | self.show_default = val; 316 | self 317 | } 318 | 319 | /// Registers a validator. 320 | /// 321 | /// # Example 322 | /// 323 | /// ```no_run 324 | /// # use dialoguer::Input; 325 | /// let mail: String = Input::new() 326 | /// .with_prompt("Enter email") 327 | /// .validate_with(|input: &String| -> Result<(), &str> { 328 | /// if input.contains('@') { 329 | /// Ok(()) 330 | /// } else { 331 | /// Err("This is not a mail address") 332 | /// } 333 | /// }) 334 | /// .interact() 335 | /// .unwrap(); 336 | /// ``` 337 | pub fn validate_with(&mut self, mut validator: V) -> &mut Input<'a, T> 338 | where 339 | V: Validator + 'a, 340 | T: 'a, 341 | { 342 | let mut old_validator_func = self.validator.take(); 343 | 344 | self.validator = Some(Box::new(move |value: &T| -> Option> { 345 | if let Some(old) = old_validator_func.as_mut() { 346 | if let Some(err) = old(value) { 347 | return Some(err); 348 | } 349 | } 350 | 351 | match validator.validate(value) { 352 | Ok(()) => None, 353 | Err(err) => Some(err.to_string().into()), 354 | } 355 | })); 356 | 357 | self 358 | } 359 | 360 | /// Enables the user to enter a printable ascii sequence and returns the result. 361 | /// 362 | /// Its difference from [`interact`](#method.interact) is that it only allows ascii characters for string, 363 | /// while [`interact`](#method.interact) allows virtually any character to be used e.g arrow keys. 364 | /// 365 | /// The dialog is rendered on stderr. 366 | pub fn interact_text(&mut self) -> io::Result { 367 | self.interact_text_on(&Term::stderr()) 368 | } 369 | 370 | /// Like [`interact_text`](#method.interact_text) but allows a specific terminal to be set. 371 | /// 372 | /// # Panics 373 | /// If the terminal is not a tty 374 | pub fn interact_text_on(&mut self, term: &Term) -> io::Result { 375 | let mut render = TermThemeRenderer::new(term, self.theme); 376 | 377 | loop { 378 | let default_string = self.default.as_ref().map(ToString::to_string); 379 | 380 | render.input_prompt( 381 | &self.prompt, 382 | if self.show_default { 383 | default_string.as_deref() 384 | } else { 385 | None 386 | }, 387 | )?; 388 | term.flush()?; 389 | 390 | // Read input by keystroke so that we can suppress ascii control characters 391 | if !term.features().is_attended() { 392 | return Ok("".to_owned().parse::().expect("Terminal is not a tty")); 393 | } 394 | 395 | let mut chars: Vec = Vec::new(); 396 | let mut position = 0; 397 | 398 | if let Some(initial) = self.initial_text.as_ref() { 399 | term.write_str(initial)?; 400 | chars = initial.chars().collect(); 401 | position = chars.len(); 402 | } 403 | 404 | loop { 405 | match term.read_key()? { 406 | Key::Backspace if position > 0 => { 407 | position -= 1; 408 | chars.remove(position); 409 | term.clear_chars(1)?; 410 | 411 | let tail: String = chars[position..].iter().collect(); 412 | 413 | if !tail.is_empty() { 414 | term.write_str(&tail)?; 415 | term.move_cursor_left(tail.len())?; 416 | } 417 | 418 | term.flush()?; 419 | } 420 | Key::Char(chr) if !chr.is_ascii_control() => { 421 | chars.insert(position, chr); 422 | position += 1; 423 | let tail: String = 424 | iter::once(&chr).chain(chars[position..].iter()).collect(); 425 | term.write_str(&tail)?; 426 | term.move_cursor_left(tail.len() - 1)?; 427 | term.flush()?; 428 | } 429 | Key::ArrowLeft if position > 0 => { 430 | term.move_cursor_left(1)?; 431 | position -= 1; 432 | term.flush()?; 433 | } 434 | Key::ArrowRight if position < chars.len() => { 435 | term.move_cursor_right(1)?; 436 | position += 1; 437 | term.flush()?; 438 | } 439 | Key::Enter => break, 440 | Key::Unknown => {} 441 | _ => (), 442 | } 443 | } 444 | let input = chars.iter().collect::(); 445 | 446 | term.clear_line()?; 447 | render.clear()?; 448 | 449 | if chars.is_empty() { 450 | if let Some(ref default) = self.default { 451 | render.input_prompt_selection(&self.prompt, &default.to_string())?; 452 | term.flush()?; 453 | return Ok(default.clone()); 454 | } else if !self.permit_empty { 455 | continue; 456 | } 457 | } 458 | 459 | match input.parse::() { 460 | Ok(value) => { 461 | if let Some(ref mut validator) = self.validator { 462 | if let Some(err) = validator(&value) { 463 | render.error(&err)?; 464 | continue; 465 | } 466 | } 467 | 468 | render.input_prompt_selection(&self.prompt, &input)?; 469 | term.flush()?; 470 | 471 | return Ok(value); 472 | } 473 | Err(err) => { 474 | render.error(&err.to_string())?; 475 | continue; 476 | } 477 | } 478 | } 479 | } 480 | 481 | /// Enables user interaction and returns the result. 482 | /// 483 | /// Allows any characters as input, including e.g arrow keys. 484 | /// Some of the keys might have undesired behavior. 485 | /// For more limited version, see [`interact_text`](#method.interact_text). 486 | /// 487 | /// If the user confirms the result is `true`, `false` otherwise. 488 | /// The dialog is rendered on stderr. 489 | pub fn interact(&mut self) -> io::Result { 490 | self.interact_on(&Term::stderr()) 491 | } 492 | 493 | /// Like [`interact`](#method.interact) but allows a specific terminal to be set. 494 | pub fn interact_on(&mut self, term: &Term) -> io::Result { 495 | let mut render = TermThemeRenderer::new(term, self.theme); 496 | 497 | loop { 498 | let default_string = self.default.as_ref().map(ToString::to_string); 499 | 500 | render.input_prompt( 501 | &self.prompt, 502 | if self.show_default { 503 | default_string.as_deref() 504 | } else { 505 | None 506 | }, 507 | )?; 508 | term.flush()?; 509 | 510 | let input = if let Some(initial_text) = self.initial_text.as_ref() { 511 | term.read_line_initial_text(initial_text)? 512 | } else { 513 | term.read_line()? 514 | }; 515 | 516 | render.add_line(); 517 | term.clear_line()?; 518 | render.clear()?; 519 | 520 | if input.is_empty() { 521 | if let Some(ref default) = self.default { 522 | render.input_prompt_selection(&self.prompt, &default.to_string())?; 523 | term.flush()?; 524 | return Ok(default.clone()); 525 | } else if !self.permit_empty { 526 | continue; 527 | } 528 | } 529 | 530 | match input.parse::() { 531 | Ok(value) => { 532 | if let Some(ref mut validator) = self.validator { 533 | if let Some(err) = validator(&value) { 534 | render.error(&err)?; 535 | continue; 536 | } 537 | } 538 | 539 | render.input_prompt_selection(&self.prompt, &input)?; 540 | term.flush()?; 541 | 542 | return Ok(value); 543 | } 544 | Err(err) => { 545 | render.error(&err.to_string())?; 546 | continue; 547 | } 548 | } 549 | } 550 | } 551 | } 552 | -------------------------------------------------------------------------------- /src/cli/prompt/mod.rs: -------------------------------------------------------------------------------- 1 | pub mod input; 2 | pub mod prompts; 3 | -------------------------------------------------------------------------------- /src/cli/prompt/prompts.rs: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2021 Volt Contributors 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | use crate::cli::prompt::input; 18 | 19 | use dialoguer::{console, theme::ColorfulTheme}; 20 | use std::{borrow::Cow, io::Result}; 21 | 22 | /// Prompt that returns `true` or `false` (as strings) 23 | #[derive(Debug)] 24 | pub struct Confirm<'i> { 25 | /// Message for the prompt 26 | pub message: Cow<'i, str>, 27 | 28 | /// Default value for the prompt is `true` 29 | pub default: bool, 30 | // TODO: Validation 31 | // #[structopt(short, long)] 32 | // /// Command to validate the submitted value 33 | // validate: Option, 34 | } 35 | 36 | impl<'i> Confirm<'i> { 37 | pub fn run(&self) -> Result { 38 | let theme = ColorfulTheme { 39 | defaults_style: console::Style::new(), 40 | prompt_style: console::Style::new(), 41 | prompt_prefix: console::style(String::from("?")).yellow().bright(), 42 | prompt_suffix: console::style(String::from(">")).blue().dim(), 43 | success_prefix: console::style(String::from("✔")).green().bright(), 44 | success_suffix: console::style(String::from("·")).blue().dim(), 45 | error_prefix: console::style(String::from("❌")).bright().red(), 46 | error_style: console::Style::new(), 47 | hint_style: console::Style::new(), 48 | values_style: console::Style::new(), 49 | active_item_style: console::Style::new(), 50 | inactive_item_style: console::Style::new(), 51 | active_item_prefix: console::style(String::from("✔")).bright().green(), 52 | inactive_item_prefix: console::style(String::from(" ")), 53 | checked_item_prefix: console::style(String::from("")), 54 | unchecked_item_prefix: console::style(String::from("")), 55 | picked_item_prefix: console::style(String::from("")), 56 | unpicked_item_prefix: console::style(String::from("")), 57 | inline_selections: false, 58 | }; 59 | 60 | let value = dialoguer::Confirm::with_theme(&theme) 61 | .with_prompt(self.message.clone().into_owned()) 62 | .default(self.default) 63 | .interact()?; 64 | 65 | Ok(value) 66 | } 67 | } 68 | 69 | /// Prompt that takes user input and returns a string. 70 | #[derive(Debug)] 71 | pub struct Input<'i> { 72 | /// Message for the prompt 73 | pub message: Cow<'i, str>, 74 | 75 | /// Default value for the prompt 76 | pub default: Option>, 77 | 78 | /// Allow empty input. Conflicts with `default` 79 | pub allow_empty: bool, 80 | } 81 | 82 | impl Input<'_> { 83 | /// # Panics 84 | /// Can panic if cannot get self.default as ref 85 | pub fn run(&self) -> Result { 86 | let theme = ColorfulTheme { 87 | defaults_style: console::Style::new(), 88 | prompt_style: console::Style::new(), 89 | prompt_prefix: console::style(String::from("?")).yellow().bright(), 90 | prompt_suffix: console::style(String::from(">")).blue().dim(), 91 | success_prefix: console::style(String::from("✔")).green().bright(), 92 | success_suffix: console::style(String::from("·")).blue().dim(), 93 | error_prefix: console::style(String::from("❌")).bright().red(), 94 | error_style: console::Style::new(), 95 | hint_style: console::Style::new(), 96 | values_style: console::Style::new(), 97 | active_item_style: console::Style::new(), 98 | inactive_item_style: console::Style::new(), 99 | active_item_prefix: console::style(String::from("✔")).bright().green(), 100 | inactive_item_prefix: console::style(String::from(" ")), 101 | checked_item_prefix: console::style(String::from("")), 102 | unchecked_item_prefix: console::style(String::from("")), 103 | picked_item_prefix: console::style(String::from("")), 104 | unpicked_item_prefix: console::style(String::from("")), 105 | inline_selections: false, 106 | }; 107 | 108 | let mut input = input::Input::::with_theme(&theme); 109 | 110 | input 111 | .with_prompt(self.message.clone()) 112 | .allow_empty(self.allow_empty); 113 | 114 | if self.default.is_some() { 115 | input.default( 116 | self.default 117 | .as_ref() 118 | .expect("cannot get self.default asref") 119 | .to_string(), 120 | ); 121 | } 122 | 123 | let value = input.interact_text()?; 124 | 125 | Ok(value) 126 | } 127 | } 128 | /// Prompt that takes user input, hides it from the terminal, and returns a string 129 | #[derive(Debug)] 130 | pub struct Secret<'i> { 131 | /// Message for the prompt 132 | pub message: Cow<'i, str>, 133 | 134 | /// Enable confirmation prompt with this message 135 | pub confirm: Option>, 136 | 137 | /// Error message when secrets doesn't match during confirmation 138 | pub error: Option>, 139 | 140 | /// Allow empty secret 141 | pub allow_empty: bool, 142 | } 143 | 144 | impl<'i> Secret<'i> { 145 | #[allow(dead_code)] 146 | pub fn run(&self) -> Result { 147 | let theme = ColorfulTheme::default(); 148 | let mut input = dialoguer::Password::with_theme(&theme); 149 | 150 | input 151 | .with_prompt(self.message.clone()) 152 | .allow_empty_password(self.allow_empty); 153 | 154 | if let (Some(confirm), Some(error)) = (&self.confirm, &self.error) { 155 | input.with_confirmation(confirm.clone().into_owned(), error.clone().into_owned()); 156 | } 157 | 158 | let value = input.interact()?; 159 | 160 | Ok(value) 161 | } 162 | } 163 | 164 | /// Prompt that allows the user to select from a list of options 165 | #[derive(Debug)] 166 | pub struct Select<'i> { 167 | /// Message for the prompt 168 | pub message: Cow<'i, str>, 169 | 170 | /// Enables paging. Uses your terminal size 171 | pub paged: bool, 172 | 173 | /// Specify number of the item that will be selected by default 174 | pub selected: Option, 175 | 176 | /// Items that can be selected 177 | pub items: Vec>, 178 | } 179 | 180 | impl<'i> Select<'i> { 181 | pub fn run(&self) -> Result { 182 | let item_len = self.items.len(); 183 | 184 | if item_len == 0 { 185 | return Ok(0); 186 | } 187 | 188 | let theme = ColorfulTheme { 189 | defaults_style: console::Style::new(), 190 | prompt_style: console::Style::new().bold(), 191 | prompt_prefix: console::style(String::from("?")).yellow().bright(), 192 | prompt_suffix: console::style(String::from(">")).blue().dim(), 193 | success_prefix: console::style(String::from("✔")).green().bright(), 194 | success_suffix: console::style(String::from("·")).blue().dim(), 195 | error_prefix: console::style(String::from("❌")).bright().red(), 196 | error_style: console::Style::new(), 197 | hint_style: console::Style::new().bold(), 198 | values_style: console::Style::new(), 199 | active_item_style: console::Style::new(), 200 | inactive_item_style: console::Style::new(), 201 | active_item_prefix: console::style(String::from("✔")).bright().green(), 202 | inactive_item_prefix: console::style(String::from(" ")), 203 | checked_item_prefix: console::style(String::from("")), 204 | unchecked_item_prefix: console::style(String::from("")), 205 | picked_item_prefix: console::style(String::from("")), 206 | unpicked_item_prefix: console::style(String::from("")), 207 | inline_selections: false, 208 | }; 209 | 210 | let mut input = dialoguer::Select::with_theme(&theme); 211 | 212 | input 213 | .with_prompt(self.message.clone()) 214 | //.paged(self.paged) 215 | .items(&self.items); 216 | 217 | if let Some(selected) = self.selected { 218 | input.default(selected - 1); 219 | } 220 | 221 | input.interact() 222 | } 223 | } 224 | -------------------------------------------------------------------------------- /src/core/commands/bloat.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::cli::app::App; 19 | use anyhow::Result; 20 | use cargo_util::ProcessBuilder; 21 | use clap::Values; 22 | use colored::Colorize; 23 | use comfy_table::ContentArrangement; 24 | use comfy_table::{modifiers::UTF8_ROUND_CORNERS, presets::UTF8_FULL, Cell, Color}; 25 | use indicatif::{ProgressBar, ProgressStyle}; 26 | use std::thread::JoinHandle; 27 | 28 | use serde::{Deserialize, Serialize}; 29 | 30 | #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 31 | #[serde(rename_all = "camelCase")] 32 | pub struct BloatCrateAnalysis { 33 | #[serde(rename = "file-size")] 34 | pub file_size: i64, 35 | #[serde(rename = "text-section-size")] 36 | pub text_section_size: i64, 37 | pub crates: Vec, 38 | } 39 | 40 | #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 41 | #[serde(rename_all = "camelCase")] 42 | pub struct Crate { 43 | pub name: String, 44 | pub size: i64, 45 | } 46 | 47 | #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 48 | #[serde(rename_all = "camelCase")] 49 | pub struct BloatFunctionAnalysis { 50 | #[serde(rename = "file-size")] 51 | pub file_size: i64, 52 | #[serde(rename = "text-section-size")] 53 | pub text_section_size: i64, 54 | pub functions: Vec, 55 | } 56 | 57 | #[derive(Default, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] 58 | #[serde(rename_all = "camelCase")] 59 | pub struct Function { 60 | #[serde(rename = "crate")] 61 | pub crate_field: Option, 62 | pub name: String, 63 | pub size: i64, 64 | } 65 | 66 | /// Panics: 67 | pub fn run(_app: App, _args: Option) -> Result<()> { 68 | let mut handles: Vec> = vec![]; 69 | let spinner = ProgressBar::new_spinner(); 70 | 71 | handles.push(std::thread::spawn({ 72 | let spinner = spinner; 73 | move || -> comfy_table::Table { 74 | spinner.set_style(ProgressStyle::default_spinner().template("{spinner} {msg}")); 75 | 76 | spinner.set_message("Initializing".bright_green().to_string()); 77 | 78 | spinner.enable_steady_tick(10); 79 | 80 | let mut warning_count: u64 = 0; 81 | let mut error_count: u64 = 0; 82 | 83 | // Run cargo bloat 84 | let mut command = ProcessBuilder::new("cargo"); 85 | 86 | command 87 | .arg("bloat") 88 | .arg("--crates") 89 | .arg("--message-format=json"); 90 | 91 | let output = command.exec_with_streaming( 92 | &mut |_| Ok(()), 93 | &mut |on_stderr| { 94 | let contents = on_stderr.trim().to_string(); 95 | 96 | if !contents.is_empty() { 97 | let chunks: Vec<&str> = contents.split(' ').collect(); 98 | 99 | if contents.starts_with("Downloaded") { 100 | let name = chunks[1].to_string(); 101 | 102 | let mut version = chunks[2].to_string(); 103 | 104 | if version.starts_with('v') { 105 | version.remove(0); 106 | } 107 | 108 | spinner.set_message(format!( 109 | "{} ({}{}{})", 110 | "Download".bright_cyan(), 111 | name.bright_yellow(), 112 | "@".bright_magenta(), 113 | version.bright_black(), 114 | )); 115 | } 116 | 117 | if contents.starts_with("Compiling") { 118 | let name = chunks[1].to_string(); 119 | 120 | let mut version = chunks[2].to_string(); 121 | 122 | if version.starts_with('v') { 123 | version.remove(0); 124 | } 125 | 126 | spinner.set_message(format!( 127 | "{} ({}{}{})", 128 | "Compile".bright_cyan(), 129 | name.bright_yellow(), 130 | "@".bright_magenta(), 131 | version.bright_black(), 132 | )); 133 | } 134 | 135 | if contents.starts_with("warning:") { 136 | warning_count += 1; 137 | spinner.set_message(format!( 138 | "{} ({} {}, {} {})", 139 | "Check".bright_cyan(), 140 | warning_count.to_string().bright_magenta(), 141 | "warnings".bright_yellow(), 142 | error_count.to_string().bright_red(), 143 | "errors".bright_yellow(), 144 | )); 145 | } 146 | 147 | if contents.starts_with("error") { 148 | error_count += 1; 149 | } 150 | } 151 | 152 | Ok(()) 153 | }, 154 | true, 155 | ); 156 | 157 | if output.is_err() { 158 | spinner.finish(); 159 | 160 | // Show all errors in the codebase: 161 | std::process::Command::new("cargo") 162 | .arg("check") 163 | .status() 164 | .unwrap(); 165 | 166 | std::process::exit(1); 167 | } 168 | 169 | spinner.set_message("Analysing".bright_cyan().to_string()); 170 | 171 | let stdout = String::from_utf8(output.unwrap().stdout).unwrap(); 172 | 173 | let data = serde_json::from_str::(&stdout).unwrap(); 174 | 175 | let total_size = byte_unit::Byte::from_bytes(data.file_size as u128); 176 | let adjusted_size = total_size.get_appropriate_unit(true); 177 | 178 | println!("Total Size: {}", adjusted_size.to_string().bright_yellow()); 179 | 180 | let mut crates_table = comfy_table::Table::new(); 181 | 182 | crates_table 183 | .load_preset(UTF8_FULL) 184 | .apply_modifier(UTF8_ROUND_CORNERS) 185 | .set_content_arrangement(ContentArrangement::DynamicFullWidth); 186 | 187 | crates_table.set_header(vec!["Name", "Size"]); 188 | 189 | for crate_ in &data.crates { 190 | let size = byte_unit::Byte::from_bytes(crate_.size as u128); 191 | let adjusted_size = size.get_appropriate_unit(true); 192 | 193 | crates_table.add_row(vec![ 194 | Cell::new(crate_.name.to_string()).fg(Color::Blue), 195 | Cell::new(adjusted_size.to_string()).fg(Color::Cyan), 196 | ]); 197 | } 198 | 199 | crates_table 200 | } 201 | })); 202 | 203 | handles.push(std::thread::spawn(move || -> comfy_table::Table { 204 | let output = std::process::Command::new("cargo") 205 | .arg("bloat") 206 | .arg("--message-format=json") 207 | .output() 208 | .unwrap(); 209 | 210 | let stdout = String::from_utf8(output.stdout).unwrap(); 211 | 212 | let data = serde_json::from_str::(&stdout).unwrap(); 213 | 214 | let mut function_table = comfy_table::Table::new(); 215 | 216 | function_table 217 | .set_content_arrangement(ContentArrangement::Dynamic) 218 | .load_preset(UTF8_FULL) 219 | .apply_modifier(UTF8_ROUND_CORNERS); 220 | 221 | function_table.set_header(vec!["Crate", "Function", "Size"]); 222 | 223 | for function in &data.functions { 224 | let size = byte_unit::Byte::from_bytes(function.size as u128); 225 | let adjusted_size = size.get_appropriate_unit(true); 226 | let mut crate_field = "unknown"; 227 | 228 | if function.crate_field.is_some() { 229 | crate_field = &function.crate_field.as_ref().unwrap(); 230 | } 231 | 232 | function_table.add_row(vec![ 233 | Cell::new(crate_field.to_string()).fg(Color::Blue), 234 | Cell::new(function.name.to_string()), 235 | Cell::new(adjusted_size.to_string()).fg(Color::Cyan), 236 | ]); 237 | } 238 | 239 | function_table 240 | })); 241 | 242 | let mut tables: Vec = vec![]; 243 | 244 | for handle in handles { 245 | tables.push(handle.join().unwrap()); 246 | } 247 | 248 | for table in tables { 249 | println!("{table}"); 250 | } 251 | 252 | println!( 253 | "\n{}: All sizes shown are estimates and will not be 100% accurate.", 254 | "Note".bright_yellow() 255 | ); 256 | 257 | Ok(()) 258 | } 259 | -------------------------------------------------------------------------------- /src/core/commands/build.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::cli::app::App; 19 | use crate::core::config::enable::enable_fleet; 20 | use anyhow::Result; 21 | use clap::Values; 22 | 23 | pub fn run(app: App, args: Option) -> Result<()> { 24 | enable_fleet(app); 25 | 26 | let args = args.unwrap_or_default(); 27 | std::process::Command::new("cargo") 28 | .arg("build") 29 | .args(args) 30 | .status()?; 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /src/core/commands/configure.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::cli::app::App; 19 | use crate::cli::prompt; 20 | use anyhow::Result; 21 | use clap::Values; 22 | use colored::Colorize; 23 | 24 | /// 25 | /// # Panics 26 | /// 27 | /// can panic is fails to run 28 | pub fn run(_app: App, _args: Option) -> Result<()> { 29 | let prompt = format!("Select a {}:", "Linker".bright_cyan()); 30 | 31 | let linker_options = match std::env::consts::OS { 32 | "windows" => { 33 | vec![std::borrow::Cow::Owned(format!( 34 | "🚄 lld - {} faster", 35 | "4x".bright_cyan() 36 | ))] 37 | } 38 | "macos" => { 39 | vec![ 40 | std::borrow::Cow::Owned(format!("🚀 zld - {} faster", "6x".bright_cyan())), 41 | std::borrow::Cow::Owned(format!("🚄 lld - {} faster", "4x".bright_cyan())), 42 | ] 43 | } 44 | "linux" => { 45 | vec![ 46 | std::borrow::Cow::Owned(format!("🚀 mold - {} faster", "20x".bright_cyan())), 47 | std::borrow::Cow::Owned(format!("🚄 lld - {} faster", "5x".bright_cyan())), 48 | ] 49 | } 50 | &_ => Vec::new(), 51 | }; 52 | 53 | let select = prompt::prompts::Select { 54 | message: std::borrow::Cow::Borrowed(prompt.as_str()), 55 | paged: false, 56 | selected: None, 57 | items: linker_options.clone(), 58 | }; 59 | 60 | let linker_selected = linker_options[select.run().unwrap()].to_string(); 61 | 62 | crate::utils::configure::install_linker(&linker_selected); 63 | 64 | Ok(()) 65 | } 66 | -------------------------------------------------------------------------------- /src/core/commands/init.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::cli::app::App; 19 | use anyhow::Result; 20 | use clap::Values; 21 | 22 | pub fn run(_app: App, _args: Option) -> Result<()> { 23 | todo!() 24 | } 25 | -------------------------------------------------------------------------------- /src/core/commands/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod bloat; 19 | pub mod build; 20 | pub mod configure; 21 | pub mod init; 22 | pub mod run; 23 | 24 | pub mod udeps; 25 | -------------------------------------------------------------------------------- /src/core/commands/run.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::cli::app::App; 19 | use crate::core::config::enable::enable_fleet; 20 | use anyhow::Result; 21 | use clap::Values; 22 | 23 | pub fn run(app: App, args: Option) -> Result<()> { 24 | enable_fleet(app); 25 | 26 | let args = args.unwrap_or_default(); 27 | std::process::Command::new("cargo") 28 | .arg("run") 29 | .args(args) 30 | .status()?; 31 | 32 | Ok(()) 33 | } 34 | -------------------------------------------------------------------------------- /src/core/commands/udeps.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::collections::HashMap; 19 | 20 | use crate::cli::app::App; 21 | use anyhow::Result; 22 | use cargo_util::ProcessBuilder; 23 | use clap::Values; 24 | use colored::Colorize; 25 | use indicatif::{ProgressBar, ProgressStyle}; 26 | 27 | use ptree::print_tree_with; 28 | use ptree::Color; 29 | use ptree::PrintConfig; 30 | use ptree::Style; 31 | use ptree::TreeBuilder; 32 | use serde::Deserialize; 33 | use serde::Serialize; 34 | 35 | #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] 36 | #[serde(rename_all = "camelCase")] 37 | pub struct UdepsAnalysis { 38 | pub success: bool, 39 | #[serde(rename = "unused_deps")] 40 | pub unused_deps: Option>, 41 | pub note: Option, 42 | } 43 | 44 | #[derive(Default, Debug, Clone, PartialEq, Serialize, Deserialize)] 45 | #[serde(rename_all = "camelCase")] 46 | pub struct UnusedDep { 47 | #[serde(rename = "manifest_path")] 48 | pub manifest_path: String, 49 | pub normal: Option>, 50 | pub development: Option>, 51 | pub build: Option>, 52 | } 53 | 54 | pub fn pretty_print_notes(_args: Option) { 55 | let false_positive_note = format!( 56 | r#" 57 | {}: There might be false positives. 58 | For example, `{}` cannot detect crates only used in doc-tests. 59 | To ignore dependencies, write `{}` in {}."#, 60 | "Note".bright_blue(), 61 | "fleet udeps".bright_cyan(), 62 | "package.metadata.cargo-udeps.ignore".bright_green(), 63 | "Cargo.toml".bright_yellow(), 64 | ); 65 | 66 | println!("{false_positive_note}"); 67 | 68 | let all_targets_note = format!( 69 | r#" 70 | {}: These dependencies might be used by other targets. 71 | To find dependencies that are not used by any target, enable `{}`."#, 72 | "Note".bright_blue(), 73 | "--all-targets".bright_cyan(), 74 | ); 75 | 76 | println!("{all_targets_note}"); 77 | } 78 | 79 | pub fn pretty_print_udeps_analysis(analysis: UdepsAnalysis) { 80 | if let Some(unused_deps) = analysis.unused_deps { 81 | for (crate_name, dependencies) in unused_deps.iter() { 82 | let split = crate_name.split(' ').collect::>(); 83 | 84 | let name = split[0].trim(); 85 | let version = split[1].trim(); 86 | 87 | let mut unused_dependencies_found = false; 88 | 89 | if let Some(normal) = &dependencies.normal { 90 | if !normal.is_empty() { 91 | unused_dependencies_found = true; 92 | } 93 | } 94 | 95 | if let Some(development) = &dependencies.development { 96 | if !development.is_empty() { 97 | unused_dependencies_found = true; 98 | } 99 | } 100 | 101 | if let Some(build) = &dependencies.build { 102 | if !build.is_empty() { 103 | unused_dependencies_found = true; 104 | } 105 | } 106 | 107 | if unused_dependencies_found { 108 | let mut tree = TreeBuilder::new(format!( 109 | "unused deps for {}{}{}", 110 | name.bright_yellow(), 111 | "@".bright_magenta(), 112 | version.bright_black() 113 | )); 114 | 115 | if let Some(normal) = &dependencies.normal { 116 | if !normal.is_empty() { 117 | tree.begin_child("dependencies".bright_green().to_string()); 118 | for unused_dependency in normal { 119 | tree.add_empty_child(unused_dependency.to_string()); 120 | } 121 | tree.end_child(); 122 | } 123 | } 124 | 125 | if let Some(development) = &dependencies.development { 126 | if !development.is_empty() { 127 | tree.begin_child("dev-dependencies".bright_blue().to_string()); 128 | for unused_dependency in development { 129 | tree.add_empty_child(unused_dependency.to_string()); 130 | } 131 | tree.end_child(); 132 | } 133 | } 134 | 135 | if let Some(build) = &dependencies.build { 136 | if !build.is_empty() { 137 | tree.begin_child("build-dependencies".bright_cyan().to_string()); 138 | for unused_dependency in build { 139 | tree.add_empty_child(unused_dependency.to_string()); 140 | } 141 | tree.end_child(); 142 | } 143 | } 144 | 145 | let mut print_config = PrintConfig::default(); 146 | let mut style = Style::default(); 147 | style.foreground = Some(Color::RGB(128, 128, 128)); 148 | 149 | print_config.branch = style; 150 | 151 | print_tree_with(&tree.build(), &print_config).unwrap(); 152 | } else { 153 | continue; 154 | } 155 | } 156 | 157 | pretty_print_notes(None); 158 | } 159 | } 160 | 161 | /// Panics: 162 | pub fn run(_app: App, _args: Option) -> Result<()> { 163 | // Run cargo bloat 164 | let mut command = ProcessBuilder::new("cargo"); 165 | let spinner = ProgressBar::new_spinner(); 166 | 167 | command.arg("udeps").arg("--output=json"); 168 | 169 | spinner.set_style(ProgressStyle::default_spinner().template("{spinner} {msg}")); 170 | 171 | spinner.set_message("Analysing".bright_green().to_string()); 172 | 173 | spinner.enable_steady_tick(10); 174 | 175 | let mut warning_count: u64 = 0; 176 | let mut error_count: u64 = 0; 177 | 178 | let mut stdout_contents: String = String::new(); 179 | 180 | let output = command.exec_with_streaming( 181 | &mut |on_stdout| { 182 | // spinner.println(format!("Stdout: {}", on_stdout)); 183 | stdout_contents.push_str(&on_stdout); 184 | Ok(()) 185 | }, 186 | &mut |on_stderr| { 187 | // spinner.println(format!("Stderr: {}", on_stderr)); 188 | 189 | let contents = on_stderr.trim().to_string(); 190 | 191 | if !contents.is_empty() { 192 | let chunks: Vec<&str> = contents.split(' ').collect(); 193 | 194 | if contents.starts_with("Compiling") { 195 | let name = chunks[1].to_string(); 196 | 197 | let mut version = chunks[2].to_string(); 198 | 199 | if version.starts_with('v') { 200 | version.remove(0); 201 | } 202 | 203 | spinner.set_message(format!( 204 | "{} ({}{}{})", 205 | "Compile".bright_cyan(), 206 | name.bright_yellow(), 207 | "@".bright_magenta(), 208 | version.bright_black(), 209 | )); 210 | } 211 | 212 | if contents.starts_with("warning:") { 213 | warning_count += 1; 214 | spinner.set_message(format!( 215 | "{} ({} {}, {} {})", 216 | "Check".bright_cyan(), 217 | warning_count.to_string().bright_magenta(), 218 | "warnings".bright_yellow(), 219 | error_count.to_string().bright_red(), 220 | "errors".bright_yellow(), 221 | )); 222 | } 223 | 224 | if contents.starts_with("error") { 225 | error_count += 1; 226 | } 227 | } 228 | 229 | Ok(()) 230 | }, 231 | true, 232 | ); 233 | 234 | if output.is_err() { 235 | spinner.finish(); 236 | 237 | if output 238 | .as_ref() 239 | .err() 240 | .unwrap() 241 | .to_string() 242 | .contains("exit code: 101") 243 | { 244 | // TODO: recommend to install cargo-udeps here. 245 | std::process::exit(1); 246 | } 247 | 248 | if error_count >= 1 { 249 | // Show all errors in the codebase: 250 | std::process::Command::new("cargo") 251 | .arg("check") 252 | .status() 253 | .unwrap(); 254 | 255 | std::process::exit(1); 256 | } 257 | } 258 | 259 | spinner.set_message("Analysing".bright_cyan().to_string()); 260 | 261 | let data = serde_json::from_str::(&stdout_contents.trim()).unwrap(); 262 | 263 | spinner.finish_and_clear(); 264 | 265 | pretty_print_udeps_analysis(data); 266 | 267 | Ok(()) 268 | } 269 | -------------------------------------------------------------------------------- /src/core/config/cargo.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::process::exit; 19 | 20 | use ansi_term::Colour::Red; 21 | use serde::{Deserialize, Serialize}; 22 | 23 | #[derive(Debug, Serialize, Deserialize)] 24 | pub struct ConfigToml { 25 | pub build: Build, 26 | #[serde(rename = "target")] 27 | pub target: Target, 28 | 29 | pub profile: Profile, 30 | } 31 | 32 | #[derive(Debug, Serialize, Deserialize)] 33 | pub struct ProfileValues { 34 | #[serde(rename = "opt-level")] 35 | pub opt_level: u8, 36 | pub debug: u8, 37 | pub incremental: bool, 38 | #[serde(rename = "codegen-units")] 39 | pub codegen_units: u16, 40 | } 41 | 42 | #[derive(Debug, Serialize, Deserialize)] 43 | pub struct Profile { 44 | pub dev: ProfileValues, 45 | pub release: ProfileValues, 46 | } 47 | 48 | #[derive(Debug, Serialize, Deserialize)] 49 | pub struct Build { 50 | #[serde(rename = "rustc-wrapper")] 51 | pub rustc_wrapper: Option, 52 | } 53 | 54 | #[derive(Debug, Serialize, Deserialize)] 55 | pub struct TargetValues { 56 | pub rustflags: Vec, 57 | pub linker: Option, 58 | } 59 | #[derive(Debug, Serialize, Deserialize)] 60 | pub struct Target { 61 | #[serde(rename = "x86_64-unknown-linux-gnu")] 62 | pub linux: TargetValues, 63 | #[serde(rename = "x86_64-pc-windows-msvc")] 64 | pub windows: TargetValues, 65 | #[serde(rename = "x86_64-apple-darwin")] 66 | pub mac: TargetValues, 67 | } 68 | 69 | /// 70 | /// Creates and writes the config into `./.cargo/config.toml` 71 | /// 72 | /// The `./.cargo/config.toml` is used by `cargo` to choose the building/running of a crate with rustc. 73 | /// 74 | /// 75 | /// # Panics 76 | /// Can panic if cannot prettify config 77 | pub fn add_rustc_wrapper_and_target_configs( 78 | path: &str, 79 | sccache_path: Option, 80 | clang_path: Option, 81 | lld_path: Option, 82 | zld_path: Option, 83 | ) { 84 | let mut config: ConfigToml = ConfigToml { 85 | build: Build { 86 | rustc_wrapper: sccache_path, 87 | }, 88 | target: Target { 89 | mac: TargetValues { 90 | rustflags: vec![ 91 | String::from("-C"), 92 | String::from("-Zshare-generics=y"), 93 | String::from("-Csplit-debuginfo=unpacked"), 94 | ], 95 | linker: None, 96 | }, 97 | windows: TargetValues { 98 | rustflags: vec![String::from("-Zshare-generics=y")], 99 | linker: lld_path, 100 | }, 101 | linux: TargetValues { 102 | rustflags: vec![ 103 | String::from("-Clink-arg=-fuse-ld=lld"), 104 | String::from("-Zshare-generics=y"), 105 | ], 106 | linker: clang_path, 107 | }, 108 | }, 109 | profile: Profile { 110 | release: ProfileValues { 111 | opt_level: 3, 112 | debug: 0, 113 | incremental: false, 114 | codegen_units: 256, 115 | }, 116 | dev: ProfileValues { 117 | codegen_units: 512, 118 | debug: 2, 119 | incremental: true, 120 | opt_level: 0, 121 | }, 122 | }, 123 | }; 124 | 125 | if let Some(zld) = zld_path { 126 | config 127 | .target 128 | .mac 129 | .rustflags 130 | .push(format!("link-arg=-fuse-ld={}", zld)); 131 | } 132 | 133 | let toml_string = toml::to_string_pretty(&config).expect("Cannot prettify config"); 134 | 135 | std::fs::write(path, toml_string).unwrap_or_else(|err| { 136 | eprintln!( 137 | "{}: failed to write configuration: {}", 138 | Red.paint("error"), 139 | err 140 | ); 141 | 142 | exit(1); 143 | }); 144 | 145 | println!("📝 Generated Fleet Config"); 146 | } 147 | -------------------------------------------------------------------------------- /src/core/config/enable.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::core::config::cargo::add_rustc_wrapper_and_target_configs; 19 | use ansi_term::Colour::{Green, Red}; 20 | use std::{ 21 | path::{self, PathBuf}, 22 | process::{exit, Command}, 23 | }; 24 | 25 | /// Unwraps a item of Option and returns the path as a String in Option 26 | fn string_path_unwrap(path: Option) -> Option { 27 | path.map(|path| path.to_str().unwrap().to_string()) 28 | } 29 | 30 | #[cfg(unix)] 31 | #[allow(unused_imports)] 32 | use sysinfo::{DiskExt, DiskType, RefreshKind, System, SystemExt}; 33 | 34 | /// If the `./.cargo/config.toml` doesn't exist, it is created. 35 | /// 36 | /// The application config is written onto the `./.cargo/config.toml`. 37 | /// 38 | /// Ramdisk improvements are applied if the disk is a HDD and the program is using WSL 39 | /// 40 | /// # Panics 41 | /// Can panic if cannot get `dirs::home_dir` 42 | pub fn enable_fleet(app: crate::cli::app::App) { 43 | let cargo_toml = path::Path::new("./Cargo.toml"); 44 | 45 | if !cargo_toml.exists() { 46 | if let Err(cmd) = Command::new("cargo").arg("init").status() { 47 | eprintln!("{}: failed to run cargo init: {}", Red.paint("error"), cmd); 48 | exit(1); 49 | } 50 | } 51 | 52 | let config = app.config; 53 | let os = std::env::consts::OS; 54 | 55 | if os != "windows" { 56 | // ramdisk improvements are only found if the disk is a HDD and the program is using WSL 57 | #[cfg(target_os = "linux")] 58 | { 59 | let refresh_kind = RefreshKind::new(); 60 | let disks = refresh_kind.with_disks_list(); 61 | let system = System::new_with_specifics(disks); 62 | let disk = system.disks().get(0).unwrap(); 63 | 64 | if disk.type_() == DiskType::HDD || wsl::is_wsl() { 65 | let ramdisk_dir = path::Path::new("/dev/shm"); 66 | let fleet_dir = ramdisk_dir.join(&config.fleet_id); 67 | let target_dir = std::env::current_dir().unwrap().join("target"); 68 | 69 | // check if target_dir is not a symlink, if yes delete it 70 | if !target_dir.is_symlink() && target_dir.exists() { 71 | if let Err(err) = std::fs::remove_dir_all(target_dir.clone()) { 72 | eprintln!("{} {}", Red.paint("error: "), &err); 73 | exit(1) 74 | } 75 | } 76 | 77 | if !fleet_dir.exists() { 78 | if let Err(err) = std::fs::create_dir(fleet_dir.clone()) { 79 | eprintln!("{} {}", Red.paint("error: "), &err); 80 | exit(1) 81 | } 82 | } 83 | 84 | if !target_dir.exists() { 85 | println!("💽 Creating Ramdisk"); 86 | std::os::unix::fs::symlink(fleet_dir, target_dir).unwrap(); 87 | } 88 | } 89 | } 90 | } 91 | 92 | // https://doc.rust-lang.org/cargo/reference/config.html 93 | let cargo_manifest_dir = std::env::current_dir().unwrap().join(".cargo"); 94 | 95 | std::fs::create_dir_all(&cargo_manifest_dir).unwrap(); 96 | 97 | let config_toml = cargo_manifest_dir.join("config.toml"); 98 | let config_no_toml = cargo_manifest_dir.join("config"); 99 | 100 | if !config_toml.exists() && !config_no_toml.exists() { 101 | std::fs::File::create(&config_toml).unwrap_or_else(|err| { 102 | eprintln!( 103 | "{}: failed to create configuration files: {}", 104 | Red.paint("error"), 105 | err 106 | ); 107 | exit(1); 108 | }); 109 | } 110 | 111 | add_rustc_wrapper_and_target_configs( 112 | if config_toml.exists() { 113 | config_toml.to_str().unwrap() 114 | } else { 115 | config_no_toml.to_str().unwrap() 116 | }, 117 | string_path_unwrap(config.build.sccache), 118 | string_path_unwrap(config.build.clang), 119 | string_path_unwrap(config.build.lld), 120 | string_path_unwrap(config.build.zld), 121 | ); 122 | 123 | println!("🚀 {}", Green.paint("Fleet is ready!")); 124 | } 125 | -------------------------------------------------------------------------------- /src/core/config/global.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use crate::core::config::find; 19 | use serde::{Deserialize, Serialize}; 20 | use std::{fs, path::PathBuf, process::exit}; 21 | 22 | /// Represents the Build table of the global config file at `{home_dir}/.config/fleet/config.toml` 23 | #[derive(Deserialize, Debug, Serialize, Clone)] 24 | pub struct Build { 25 | pub sccache: Option, 26 | pub lld: Option, 27 | pub clang: Option, 28 | pub zld: Option, 29 | } 30 | /// Represents the Build table of the global config file at `{home_dir}/.config/fleet/config.toml` 31 | #[derive(Deserialize, Debug, Serialize, Clone)] 32 | pub struct FleetGlobalConfig { 33 | pub build: Build, 34 | } 35 | 36 | impl FleetGlobalConfig { 37 | /// If the global fleet config file is not found, it is created with the basic settings and the config is returned. 38 | /// 39 | /// If the file exists at `{home_dir}/.config/fleet`, it is read and parsed into a `FleetGlobalConfig` instance and returned. 40 | /// 41 | /// # Panics 42 | /// can panic if home dir not found 43 | pub fn run_config() -> Self { 44 | let config_dir = dirs::home_dir().unwrap().join(".config").join("fleet"); 45 | 46 | if !config_dir.join(".config").join("fleet").exists() { 47 | fs::create_dir_all(&config_dir).unwrap(); 48 | } 49 | 50 | let config_path = config_dir.join("config.toml"); 51 | 52 | if config_path.exists() { 53 | let config_file = fs::read_to_string(&config_path).unwrap(); 54 | if let Ok(config) = toml::from_str::(&config_file) { 55 | return config; 56 | } 57 | 58 | println!("Invalid fleet global configuration"); 59 | exit(1) 60 | } 61 | 62 | let config = FleetGlobalConfig { 63 | build: Build { 64 | sccache: find("sccache"), 65 | lld: Some(PathBuf::from("rust-lld.exe")), 66 | clang: find("clang"), 67 | zld: find("zld"), 68 | }, 69 | }; 70 | 71 | fs::write(config_path, toml::to_string(&config).unwrap()) 72 | .expect("Failed to generate Fleet Global Config"); 73 | 74 | println!("📝 Generated Fleet Global Config"); 75 | 76 | config 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/core/config/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /// Handles configuration of the fleet setup and execution 19 | pub mod cargo; 20 | pub mod enable; 21 | pub mod global; 22 | 23 | use global::FleetGlobalConfig; 24 | use serde::{Deserialize, Serialize}; 25 | use std::{path::PathBuf, process::exit}; 26 | use which::which; 27 | 28 | /// Finds the path of a binary 29 | /// 30 | /// Finds the path of a binary and returns the path if it exists 31 | #[must_use] 32 | pub fn find(bin: &str) -> Option { 33 | if let Ok(path) = which(bin) { 34 | Some(path) 35 | } else { 36 | None 37 | } 38 | } 39 | 40 | /// Represents the build table of the `fleet.toml` file 41 | #[derive(Deserialize, Debug, Serialize, Clone)] 42 | pub struct Build { 43 | pub sccache: Option, 44 | pub lld: Option, 45 | pub clang: Option, 46 | pub zld: Option, 47 | } 48 | 49 | /// Represents the `fleet.toml` file 50 | #[derive(Deserialize, Debug, Serialize, Clone)] 51 | pub struct FleetConfig { 52 | pub rd_enabled: bool, 53 | pub fleet_id: String, 54 | pub build: Build, 55 | } 56 | 57 | impl Default for FleetConfig { 58 | fn default() -> Self { 59 | Self::new() 60 | } 61 | } 62 | 63 | impl FleetConfig { 64 | /// Initialize an empty `FleetConfig` instance with empty data 65 | #[must_use] 66 | pub fn new() -> Self { 67 | Self { 68 | rd_enabled: false, 69 | fleet_id: String::from(""), 70 | build: Build { 71 | sccache: None, 72 | lld: None, 73 | clang: None, 74 | zld: None, 75 | }, 76 | } 77 | } 78 | 79 | /// Creates and read the `fleet.toml` file 80 | /// 81 | /// 82 | /// If the fleet.toml does not exist, it is created with the basic settings and the basic config is returned. 83 | /// 84 | /// If it does exist, the `fleet.toml` file is read and the data is parsed into `FleetConfig` and returned. 85 | /// 86 | /// When a particular field of the `build` table is empty, it is substituted with the value from the global fleet config. 87 | /// 88 | /// T 89 | /// # Panics 90 | /// Can panic if cannot find home directory 91 | #[must_use] 92 | pub fn run_config() -> Self { 93 | let global_config = FleetGlobalConfig::run_config(); 94 | 95 | let config_path = std::env::current_dir() 96 | .expect("cannot find current directory") 97 | .join("fleet.toml"); 98 | 99 | if config_path.exists() { 100 | let config_file = std::fs::read_to_string(config_path).unwrap(); 101 | let config = toml::from_str::(&config_file); 102 | 103 | if let Ok(mut config) = config { 104 | if config.build.sccache.is_none() { 105 | config.build.sccache = global_config.build.sccache; 106 | } 107 | 108 | if config.build.lld.is_none() { 109 | config.build.lld = global_config.build.lld; 110 | } 111 | 112 | if config.build.clang.is_none() { 113 | config.build.clang = global_config.build.clang; 114 | } 115 | 116 | if config.build.zld.is_none() { 117 | config.build.zld = global_config.build.zld; 118 | } 119 | 120 | config 121 | } else { 122 | eprintln!("Invalid fleet configuration"); 123 | exit(1) 124 | } 125 | } else { 126 | let config = FleetConfig { 127 | rd_enabled: true, 128 | fleet_id: uuid::Uuid::new_v4().to_string(), 129 | build: Build { 130 | sccache: None, 131 | lld: None, 132 | clang: None, 133 | zld: None, 134 | }, 135 | }; 136 | let config_file = toml::to_string(&config).unwrap(); 137 | std::fs::write(config_path, config_file).unwrap(); 138 | config 139 | } 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /src/core/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | pub mod commands; 19 | pub mod config; 20 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | //! 19 | //! Fleet is the blazing fast build tool for Rust. Compiling with Fleet is up-to 5x faster than with cargo. 20 | //! 21 | //! Note: Since fleet is in the beta phase, it might not be completely stable yet. Feel free to open any issues or bug reports at issues. 22 | //! 23 | //! Note: As of now fleet only supports rustc nightly 24 | //! 25 | #![warn(clippy::all)] 26 | #![warn(clippy::pedantic)] 27 | #![allow( 28 | clippy::missing_errors_doc, 29 | clippy::module_name_repetitions, 30 | clippy::unused_self 31 | )] 32 | 33 | use anyhow::Result; 34 | use cli::app::App; 35 | use human_panic::setup_panic; 36 | 37 | pub mod cli; 38 | pub mod core; 39 | pub mod utils; 40 | 41 | /// Entrypoint to the CLI application 42 | fn main() -> Result<()> { 43 | // Human panic messages are only shown in `release` mode 44 | setup_panic!(); 45 | 46 | #[cfg(windows)] 47 | let _ = ansi_term::enable_ansi_support(); 48 | 49 | App::new().run() 50 | } 51 | -------------------------------------------------------------------------------- /src/utils/configure.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | use std::env::consts::OS; 19 | 20 | use colored::Colorize; 21 | 22 | /// Installs a linker 23 | /// 24 | /// Installs the specified linker using the appropriate 25 | /// package manager for the user operating system 26 | /// 27 | /// # Panics 28 | /// Can panic if unable to install clang and lld 29 | pub fn install_linker(linker: &str) { 30 | match OS { 31 | "windows" => { 32 | if linker.contains("lld") { 33 | // LLD ships with Rust: 34 | println!("🚄 lld {}", "enabled".bright_green()); 35 | } 36 | } 37 | "linux" => { 38 | if linker.contains("mold") { 39 | println!("🚀 mold {}", "enabled".bright_green()); 40 | } 41 | 42 | if linker.contains("lld") { 43 | println!( 44 | "{} {}", 45 | "$".bright_black(), 46 | "sudo apt install clang lld".bright_yellow() 47 | ); 48 | 49 | // TODO: allow for user confirmation on whether or not they want to run the command 50 | // TODO: add distro support 51 | println!("{:?}", sys_info::linux_os_release()); 52 | 53 | let result = std::process::Command::new("bash") 54 | .arg("-c") 55 | .arg("sudo apt install clang lld") 56 | .status() 57 | .expect("Failed to install clang + lld"); 58 | 59 | if result.success() { 60 | println!("🚄 lld {}", "enabled".bright_green()); 61 | } 62 | } 63 | } 64 | "macos" => { 65 | if linker.contains("zld") { 66 | println!( 67 | "{} {}", 68 | "$".bright_black(), 69 | "brew install michaeleisel/zld/zld".bright_yellow() 70 | ); 71 | 72 | // TODO: allow for user confirmation on whether or not they want to run the command 73 | // Spawn the command 74 | let result = std::process::Command::new("bash") 75 | .arg("-c") 76 | .arg("brew install michaeleisel/zld/zld") 77 | .status() 78 | .unwrap(); 79 | 80 | if result.success() { 81 | println!("🚀 zld {}", "enabled".bright_green()); 82 | } 83 | } 84 | 85 | if linker.contains("lld") { 86 | println!( 87 | "{} {}", 88 | "$".bright_black(), 89 | "sudo apt install clang lld".bright_yellow() 90 | ); 91 | 92 | // TODO: allow for user confirmation on whether or not they want to run the command 93 | let result = std::process::Command::new("bash") 94 | .arg("-c") 95 | .arg("sudo apt install clang lld") 96 | .status() 97 | .unwrap(); 98 | 99 | if result.success() { 100 | println!("🚄 lld {}", "enabled".bright_green()); 101 | } 102 | } 103 | } 104 | &_ => {} 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/utils/mod.rs: -------------------------------------------------------------------------------- 1 | /* 2 | * 3 | * Copyright 2021 Fleet Contributors 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in writing, software 12 | * distributed under the License is distributed on an "AS IS" BASIS, 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | * See the License for the specific language governing permissions and 15 | * limitations under the License. 16 | */ 17 | 18 | /// Utility features used within the fleet application 19 | pub mod configure; 20 | -------------------------------------------------------------------------------- /todo.md: -------------------------------------------------------------------------------- 1 | # Integrations 2 | 3 | Integrate: 4 | > cargo-make 5 | > cargo-hack 6 | > cargo-watch 7 | > cargo-tarpaulin 8 | > crates in cargo-extras 9 | > cargo-cache 10 | > cargo-outdated 11 | > cargo-when 12 | > cargo-audit 13 | > cargo-license --------------------------------------------------------------------------------