diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c29d3c2..c27150d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,109 +1,109 @@ -name: Build - +name: main on: - pull_request: push: + branches: + - main tags: - - 'v*' - -env: - CARGO_TERM_COLOR: always - + - "*" + pull_request: jobs: - build-linux: - name: build-${{matrix.target}} + pre-commit: runs-on: ubuntu-latest - timeout-minutes: 5 - strategy: - fail-fast: true - matrix: - target: - - aarch64-unknown-linux-gnu - - x86_64-unknown-linux-gnu steps: - - uses: actions/checkout@v3 - - uses: taiki-e/install-action@cross - - run: | - export CROSS=1 - scripts/build.sh mod_installer --release --target ${{matrix.target}} - - uses: actions/upload-artifact@v3 - with: - name: mod_installer-${{matrix.target}} - path: | - dist/bin/* - LICENSE - README.md - if-no-files-found: error - build-macos: - name: build-${{matrix.target}} - runs-on: macos-latest - timeout-minutes: 5 + - uses: actions/checkout@v3.0.2 + with: + set-safe-directory: true + - uses: actions/setup-python@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - uses: pre-commit/action@v2.0.0 + build: + runs-on: ${{ matrix.os }} strategy: - fail-fast: true matrix: - target: - - x86_64-apple-darwin - - aarch64-apple-darwin + include: + - os: macos-latest + target: x86_64-apple-darwin + suffix: '' + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + suffix: '' + - os: windows-latest + target: x86_64-pc-windows-msvc + suffix: .exe steps: - - uses: actions/checkout@v3 - - name: Install minimal stable - uses: actions-rs/toolchain@v1 + - uses: actions/checkout@v3.0.2 + - uses: actions-rs/toolchain@v1 with: - profile: minimal toolchain: stable - - run: rustup target add ${{matrix.target}} - - run: scripts/build.sh mod_installer --release --target ${{matrix.target}} - - uses: actions/upload-artifact@v3 - with: - name: mod_installer-${{ matrix.target }} - path: | - dist/bin/* - if-no-files-found: error - build-windows: - name: build-windows - runs-on: windows-latest - timeout-minutes: 5 - strategy: - fail-fast: true - matrix: - target: - - x86_64-pc-windows-msvc - steps: - - uses: actions/checkout@v3 - - name: Install minimal stable - uses: actions-rs/toolchain@v1 + - uses: actions-rs/cargo@v1 with: - profile: minimal - toolchain: stable - - run: cargo build --release --target ${{matrix.target}} - - uses: actions/upload-artifact@v3 + command: build + args: --release + - name: Archive release artifacts + uses: actions/upload-artifact@v1 with: - name: mod_installer-${{ matrix.target }} - path: | - target/${{matrix.target}}/release/mod_installer* - if-no-files-found: error - create-release: - permissions: write-all - needs: [build-windows, build-macos, build-linux] + name: post_infinity-${{ matrix.target }}${{ matrix.suffix }} + path: ./target/release/post_infinity${{ matrix.suffix }} + release: + needs: [build, pre-commit] runs-on: ubuntu-latest if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + tag_name: ${{ steps.get_tag.outputs.git_tag }} steps: - - uses: actions/checkout@v3 + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Generate a changelog + uses: orhun/git-cliff-action@v2 + id: git-cliff + with: + config: cliff.toml + args: --verbose + env: + OUTPUT: CHANGELOG.md + - name: Print the changelog + run: cat "${{ steps.git-cliff.outputs.changelog }}" - name: Get the tag id: get_tag run: echo ::set-output name=git_tag::${GITHUB_REF/refs\/tags\//} - - name: Download Artifacts - uses: actions/download-artifact@v3 - with: - path: release/ - name: Create Release id: create_release - uses: softprops/action-gh-release@v1 + uses: ncipollo/release-action@v1.13.0 with: - fail_on_unmatched_files: true - files: release/* - tag_name: ${{ steps.get_tag.outputs.git_tag }} - generate_release_notes: true - draft: ${{ startsWith(steps.get_tag.outputs.git_tag, 'nightly') != true }} + bodyFile: ./CHANGELOG.md prerelease: ${{ startsWith(steps.get_tag.outputs.git_tag, 'nightly') }} - token: ${{ secrets.GITHUB_TOKEN }} + upload: + needs: [release] + runs-on: ubuntu-latest + strategy: + matrix: + include: + - os: macos-latest + target: x86_64-apple-darwin + suffix: '' + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + suffix: '' + - os: windows-latest + target: x86_64-pc-windows-msvc + suffix: .exe + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + steps: + - uses: actions/download-artifact@v3 + with: + name: post_infinity-${{ matrix.target }}${{ matrix.suffix }} + - name: Upload Release Asset - ${{ matrix.os }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.release.outputs.upload_url }} + asset_path: ./post_infinity${{ matrix.suffix }} + asset_name: post_infinity-${{ matrix.target }}${{ matrix.suffix }} + asset_content_type: application/octet-stream + diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..c27150d --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,109 @@ +name: main +on: + push: + branches: + - main + tags: + - "*" + pull_request: +jobs: + pre-commit: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3.0.2 + with: + set-safe-directory: true + - uses: actions/setup-python@v2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - uses: pre-commit/action@v2.0.0 + build: + runs-on: ${{ matrix.os }} + strategy: + matrix: + include: + - os: macos-latest + target: x86_64-apple-darwin + suffix: '' + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + suffix: '' + - os: windows-latest + target: x86_64-pc-windows-msvc + suffix: .exe + steps: + - uses: actions/checkout@v3.0.2 + - uses: actions-rs/toolchain@v1 + with: + toolchain: stable + - uses: actions-rs/cargo@v1 + with: + command: build + args: --release + - name: Archive release artifacts + uses: actions/upload-artifact@v1 + with: + name: post_infinity-${{ matrix.target }}${{ matrix.suffix }} + path: ./target/release/post_infinity${{ matrix.suffix }} + release: + needs: [build, pre-commit] + runs-on: ubuntu-latest + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + tag_name: ${{ steps.get_tag.outputs.git_tag }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: Generate a changelog + uses: orhun/git-cliff-action@v2 + id: git-cliff + with: + config: cliff.toml + args: --verbose + env: + OUTPUT: CHANGELOG.md + - name: Print the changelog + run: cat "${{ steps.git-cliff.outputs.changelog }}" + - name: Get the tag + id: get_tag + run: echo ::set-output name=git_tag::${GITHUB_REF/refs\/tags\//} + - name: Create Release + id: create_release + uses: ncipollo/release-action@v1.13.0 + with: + bodyFile: ./CHANGELOG.md + prerelease: ${{ startsWith(steps.get_tag.outputs.git_tag, 'nightly') }} + upload: + needs: [release] + runs-on: ubuntu-latest + strategy: + matrix: + include: + - os: macos-latest + target: x86_64-apple-darwin + suffix: '' + - os: ubuntu-latest + target: x86_64-unknown-linux-gnu + suffix: '' + - os: windows-latest + target: x86_64-pc-windows-msvc + suffix: .exe + if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/') + steps: + - uses: actions/download-artifact@v3 + with: + name: post_infinity-${{ matrix.target }}${{ matrix.suffix }} + - name: Upload Release Asset - ${{ matrix.os }} + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ needs.release.outputs.upload_url }} + asset_path: ./post_infinity${{ matrix.suffix }} + asset_name: post_infinity-${{ matrix.target }}${{ matrix.suffix }} + asset_content_type: application/octet-stream + diff --git a/Cargo.lock b/Cargo.lock index 2cb48c8..5a444c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,54 +4,105 @@ version = 3 [[package]] name = "aho-corasick" -version = "0.7.20" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac" +checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ "memchr", ] [[package]] -name = "bitflags" -version = "1.3.2" +name = "anstream" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +checksum = "2ab91ebe16eb252986481c5b62f6098f3b698a45e34b5b98200cf20dd2484a44" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] [[package]] -name = "cc" -version = "1.0.79" +name = "anstyle" +version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" [[package]] -name = "cfg-if" +name = "anstyle-parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "317b9a89c1868f5ea6ff1d9539a69f45dffc21ce321ac1fd1160dfa48c8e2140" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0699d10d2f4d628a98ee7b57b289abbc98ff3bad977cb3152709d4bf2330628" +dependencies = [ + "anstyle", + "windows-sys", +] + +[[package]] +name = "bitflags" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] [[package]] name = "clap" -version = "4.1.4" +version = "4.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f13b9c79b5d1dd500d20ef541215a6423c75829ef43117e1b4d17fd8af0b5d76" +checksum = "d04704f56c2cde07f43e8e2c154b43f216dc5c92fc98ada720177362f953b956" dependencies = [ - "bitflags", + "clap_builder", "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e231faeaca65ebd1ea3c737966bf858971cd38c3849107aa3ea7de90a804e45" +dependencies = [ + "anstream", + "anstyle", "clap_lex", - "is-terminal", - "once_cell", "strsim", - "termcolor", ] [[package]] name = "clap_derive" -version = "4.1.0" +version = "4.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8" +checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873" dependencies = [ "heck", - "proc-macro-error", "proc-macro2", "quote", "syn", @@ -59,12 +110,15 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.3.1" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "783fe232adfca04f90f56201b26d79682d4cd2625e0bc7290b95123afe558ade" -dependencies = [ - "os_str_bytes", -] +checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] name = "env_logger" @@ -81,13 +135,13 @@ dependencies = [ [[package]] name = "errno" -version = "0.2.8" +version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1" +checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480" dependencies = [ "errno-dragonfly", "libc", - "winapi", + "windows-sys", ] [[package]] @@ -114,9 +168,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" +checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" [[package]] name = "humantime" @@ -124,54 +178,40 @@ version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "io-lifetimes" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1abeb7a0dd0f8181267ff8adc397075586500b81b28a73e8a0208b00fc170fb3" -dependencies = [ - "libc", - "windows-sys", -] - [[package]] name = "is-terminal" -version = "0.4.3" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0a45d56fe973d6db23972bf5bc46f988a4a2385deac9cc29572f09daef" +checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi", - "io-lifetimes", "rustix", "windows-sys", ] [[package]] name = "libc" -version = "0.2.139" +version = "0.2.148" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79" +checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b" [[package]] name = "linux-raw-sys" -version = "0.1.4" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f051f77a7c8e6957c0696eac88f26b0117e54f52d3fc682ab19397a8812846a4" +checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db" [[package]] name = "log" -version = "0.4.17" +version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" [[package]] name = "memchr" -version = "2.5.0" +version = "2.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" +checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167" [[package]] name = "mod_installer" @@ -185,64 +225,40 @@ dependencies = [ ] [[package]] -name = "once_cell" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" - -[[package]] -name = "os_str_bytes" -version = "6.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee" - -[[package]] -name = "proc-macro-error" -version = "1.0.4" +name = "proc-macro2" +version = "1.0.67" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328" dependencies = [ - "proc-macro-error-attr", - "proc-macro2", - "quote", - "syn", - "version_check", + "unicode-ident", ] [[package]] -name = "proc-macro-error-attr" -version = "1.0.4" +name = "quote" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", - "quote", - "version_check", -] - -[[package]] -name = "proc-macro2" -version = "1.0.51" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d727cae5b39d21da60fa540906919ad737832fe0b1c165da3a34d6548c849d6" -dependencies = [ - "unicode-ident", ] [[package]] -name = "quote" -version = "1.0.23" +name = "regex" +version = "1.9.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" +checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ - "proc-macro2", + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", ] [[package]] -name = "regex" -version = "1.7.1" +name = "regex-automata" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick", "memchr", @@ -251,19 +267,18 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.6.28" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" +checksum = "dbb5fb1acd8a1a18b3dd5be62d25485eb770e05afb408a9627d14d451bae12da" [[package]] name = "rustix" -version = "0.36.8" +version = "0.38.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f43abb88211988493c1abb44a70efa56ff0ce98f233b7b276146f1f3f7ba9644" +checksum = "f25469e9ae0f3d0047ca8b93fc56843f38e6774f0914a107ff8b41be8be8e0b7" dependencies = [ "bitflags", "errno", - "io-lifetimes", "libc", "linux-raw-sys", "windows-sys", @@ -286,9 +301,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "syn" -version = "1.0.107" +version = "2.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" +checksum = "7303ef2c05cd654186cb250d29049a24840ca25d2747c25c0381c8d9e2f582e8" dependencies = [ "proc-macro2", "quote", @@ -297,33 +312,32 @@ dependencies = [ [[package]] name = "termcolor" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" +checksum = "6093bad37da69aab9d123a8091e4be0aa4a03e4d601ec641c327398315f62b64" dependencies = [ "winapi-util", ] [[package]] name = "unicode-ident" -version = "1.0.6" +version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] -name = "version_check" -version = "0.9.4" +name = "utf8parse" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" [[package]] name = "walkdir" -version = "2.3.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" dependencies = [ "same-file", - "winapi", "winapi-util", ] @@ -345,9 +359,9 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" dependencies = [ "winapi", ] @@ -360,18 +374,18 @@ checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-sys" -version = "0.45.0" +version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ "windows-targets", ] [[package]] name = "windows-targets" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ "windows_aarch64_gnullvm", "windows_aarch64_msvc", @@ -384,42 +398,42 @@ dependencies = [ [[package]] name = "windows_aarch64_gnullvm" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_msvc" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_i686_gnu" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_msvc" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_x86_64_gnu" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnullvm" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_msvc" -version = "0.42.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" diff --git a/README.md b/README.md index a270025..d4a2d58 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,14 @@ # Infinity Engine Mod Installer - /\/\ ___ __| | (_)_ __ ___| |_ __ _| | | ___ _ __ + /\/\ ___ __| | (_)_ __ ___| |_ __ _| | | ___ _ __ / \ / _ \ / _` | | | '_ \/ __| __/ _` | | |/ _ \ '__| - / /\/\ \ (_) | (_| | | | | | \__ \ || (_| | | | __/ | - \/ \/\___/ \__,_| |_|_| |_|___/\__\__,_|_|_|\___|_| + / /\/\ \ (_) | (_| | | | | | \__ \ || (_| | | | __/ | + \/ \/\___/ \__,_| |_|_| |_|___/\__\__,_|_|_|\___|_| ```sh Usage: mod_installer [OPTIONS] --log-file --game-directory --weidu-binary --mod-directories Options: - --log-file Full path to target log [env: LOG_FILE=] + --log-file Full path to target log [env: LOG_FILE=] -g, --game-directory Full path to game directory [env: GAME_DIRECTORY=] -w, --weidu-binary Full Path to weidu binary [env: WEIDU_BINARY=] -m, --mod-directories Full Path to mod directories [env: MOD_DIRECTORIES=] @@ -16,3 +16,20 @@ Options: -h, --help Print help -V, --version Print version ``` + +## Log levels + +Additional information can be shown with: +```sh +RUST_LOG=INFO mod_installer [OPTIONS] +``` + +For line by line debuging: +```sh +RUST_LOG=DEBUG mod_installer [OPTIONS] +``` + +To print everything including weidu logs: +```sh +RUST_LOG=TRACE mod_installer [OPTIONS] +``` diff --git a/src/main.rs b/src/main.rs index df58a48..11dbf82 100644 --- a/src/main.rs +++ b/src/main.rs @@ -19,10 +19,14 @@ mod weidu; fn main() { env_logger::init(); - println!(r" /\/\ ___ __| | (_)_ __ ___| |_ __ _| | | ___ _ __ "); - println!(r" / \ / _ \ / _` | | | '_ \/ __| __/ _` | | |/ _ \ '__|"); - println!(r"/ /\/\ \ (_) | (_| | | | | | \__ \ || (_| | | | __/ | "); - println!(r"\/ \/\___/ \__,_| |_|_| |_|___/\__\__,_|_|_|\___|_| "); + println!( + r" + /\/\ ___ __| | (_)_ __ ___| |_ __ _| | | ___ _ __ + / \ / _ \ / _` | | | '_ \/ __| __/ _` | | |/ _ \ '__| + / /\/\ \ (_) | (_| | | | | | \__ \ || (_| | | | __/ | + \/ \/\___/ \__,_| |_|_| |_|___/\__\__,_|_|_|\___|_| + " + ); let args = Args::parse(); create_weidu_log_if_not_exists(&args.game_directory); @@ -31,7 +35,7 @@ fn main() { let mod_folder_locations = args .mod_directories .iter() - .flat_map(|mod_folder| find_mod_folder(&weidu_mod.name, mod_folder)) + .flat_map(|mod_folder| find_mod_folder(&weidu_mod, mod_folder)) .collect::>(); let mod_folder = if let Some(mod_folder) = mod_folder_locations.first() { @@ -45,13 +49,10 @@ fn main() { if !mod_folder_present_in_game_directory(&args.game_directory, &weidu_mod.name) { log::info!( "Copying mod directory, from {:?} to, {:?}", - mod_folder.join(weidu_mod.name.clone()), + mod_folder, args.game_directory.clone().join(weidu_mod.name.clone()) ); - copy_mod_folder( - &args.game_directory, - &mod_folder.join(weidu_mod.name.clone()), - ) + copy_mod_folder(&args.game_directory, mod_folder) } let weidu_args = generate_args(&weidu_mod, &args.language); install(&args.weidu_binary, &args.game_directory, weidu_args); diff --git a/src/mod_component.rs b/src/mod_component.rs index d9abbdc..8fa50dc 100644 --- a/src/mod_component.rs +++ b/src/mod_component.rs @@ -6,7 +6,7 @@ use std::{ #[derive(Debug, PartialEq)] pub struct ModComponent { - pub install_path: String, + pub tp_file: String, pub name: String, pub lang: String, pub component: String, @@ -21,6 +21,12 @@ impl From for ModComponent { .expect("Could not get full name of mod") .to_string(); + let tp_file = install_path + .split('/') + .nth(1) + .expect("Could find tp2 file") + .to_string(); + let name = install_path .split('/') .next() @@ -43,7 +49,7 @@ impl From for ModComponent { .replace('#', ""); ModComponent { - install_path, + tp_file, name, lang, component, @@ -84,7 +90,7 @@ mod tests { assert_eq!( logs.first(), Some(&ModComponent { - install_path: "TEST_MOD_NAME_1/TEST.TP2".to_string(), + tp_file: "TEST.TP2".to_string(), name: "test_mod_name_1".to_string(), lang: "0".to_string(), component: "0".to_string() @@ -93,7 +99,7 @@ mod tests { assert_eq!( logs.last(), Some(&ModComponent { - install_path: "TEST_MOD_NAME_2/TEST.TP2".to_string(), + tp_file: "TEST.TP2".to_string(), name: "test_mod_name_2".to_string(), lang: "0".to_string(), component: "0".to_string() diff --git a/src/utils.rs b/src/utils.rs index 63265d2..27785b2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -5,6 +5,8 @@ use std::{ }; use walkdir::WalkDir; +use crate::mod_component::ModComponent; + pub fn create_weidu_log_if_not_exists(game_directory: &Path) { let weidu_log_file = game_directory.join("weidu").with_extension("log"); if !weidu_log_file.exists() { @@ -26,18 +28,27 @@ pub fn copy_mod_folder(game_directory: &Path, mod_folder: &Path) { } } -pub fn find_mod_folder(mod_name: &str, mod_dir: &Path) -> Option { +pub fn find_mod_folder(mod_component: &ModComponent, mod_dir: &Path) -> Option { WalkDir::new(mod_dir) .follow_links(true) - .max_depth(2) + .max_depth(4) .into_iter() - .flat_map(|entry| { - if let Ok(entry) = entry { - if entry.file_type().is_dir() && entry.file_name().eq_ignore_ascii_case(mod_name) { - return Some(entry.into_path()); - } + .flat_map(|entry| match entry { + Ok(entry) + if entry + .path() + .parent() + .unwrap() + .file_name() + .unwrap_or_default() + .eq_ignore_ascii_case(&mod_component.name) + && entry + .file_name() + .eq_ignore_ascii_case(&mod_component.tp_file) => + { + return Some(entry.into_path().parent().unwrap().into()); } - None + _ => None, }) .collect::>() .first() @@ -50,10 +61,16 @@ mod tests { use super::*; #[test] fn finds_mod_folder() { - let mod_name = "test_mod_name_1"; - let mod_folder = find_mod_folder(mod_name, Path::new("fixtures/mods")); + let mod_component = ModComponent { + tp_file: "TEST.TP2".to_string(), + name: "test_mod_name_1".to_string(), + lang: "0".to_string(), + component: "0".to_string(), + }; + let mod_folder = find_mod_folder(&mod_component, Path::new("fixtures/mods")); - let expected = Path::new(&format!("fixtures/mods/mod_a/{}", mod_name)).to_path_buf(); + let expected = + Path::new(&format!("fixtures/mods/mod_a/{}", mod_component.name)).to_path_buf(); assert_eq!(mod_folder, Some(expected)) } } diff --git a/src/weidu.rs b/src/weidu.rs index 5583d61..956c744 100644 --- a/src/weidu.rs +++ b/src/weidu.rs @@ -1,9 +1,22 @@ -use std::{path::PathBuf, process::Command}; +use std::{ + io::{self, BufRead, BufReader, Write}, + path::PathBuf, + process::{Command, Stdio}, +}; use crate::mod_component::ModComponent; +pub fn get_user_input() -> String { + let stdin = io::stdin(); + let mut input = String::new(); + stdin.read_line(&mut input).unwrap_or_default(); + log::debug!("User input: {}", input); + + input.to_string() +} + pub fn generate_args(weidu_mod: &ModComponent, language: &str) -> Vec { - format!("{mod_install_path} --quick-log --force-install {component} --use-lang {game_lang} --language {mod_lang}", mod_install_path = weidu_mod.install_path, component = weidu_mod.component, mod_lang = weidu_mod.lang, game_lang = language).split(' ').map(|x|x.to_string()).collect() + format!("{mod_name}/{mod_tp_file} --quick-log --yes --ask-only {component} --use-lang {game_lang} --language {mod_lang}", mod_name = weidu_mod.name, mod_tp_file = weidu_mod.tp_file, component = weidu_mod.component, mod_lang = weidu_mod.lang, game_lang = language).split(' ').map(|x|x.to_string()).collect() } pub fn install(weidu_binary: &PathBuf, game_directory: &PathBuf, weidu_args: Vec) { @@ -11,29 +24,90 @@ pub fn install(weidu_binary: &PathBuf, game_directory: &PathBuf, weidu_args: Vec let mut command = Command::new(weidu_binary); let weidu_process = command.current_dir(game_directory).args(weidu_args); - match weidu_process.output() { - Ok(output) if !output.status.success() => { - let lines = std::str::from_utf8(&output.stdout) - .unwrap_or_default() - .split('\n'); - if lines - .clone() - .any(|x| x.starts_with("INSTALLED WITH WARNINGS")) - { - lines - .filter(|x| x.contains("WARNING:")) - .for_each(|warning| log::warn!("{:#?}", warning)); - } else { - for line in lines { - log::error!("{}", line); + let mut child = weidu_process + .stdin(Stdio::piped()) + .stdout(Stdio::piped()) + .spawn() + .expect("Failed to spawn weidu process"); + + let mut reader = BufReader::new(child.stdout.as_mut().unwrap()); + let stdin = &mut child.stdin.take().expect("Failed to open stdin"); + + let mut choice_flag = 0; + while child.stderr.is_none() { + let mut text = String::new(); + if reader.read_line(&mut text).is_ok() { + if !text.is_empty() { + log::trace!("{}", text); + } + + match text { + // Choice + _ if choice_flag == 1 => { + if !text.chars().nth(1).unwrap_or_default().is_numeric() { + stdin + .write_all(get_user_input().as_bytes()) + .expect("Failed to write to stdin"); + break; + } + } + x if x.starts_with("SKIPPING: ") || x.starts_with("Already Asked About") => { + stdin + .write_all("\n".as_bytes()) + .expect("Failed to write to stdin"); + log::debug!("Skiping component"); + break; } - panic!("Failed to install mod"); + x if (x.trim_end().ends_with("[Q]uit or choose one:") + || x.trim_end().starts_with("Enter ")) + && !x.to_ascii_lowercase().starts_with("[r]e-install") => + { + log::trace!("Choice found"); + choice_flag = 1; + } + + // Success + x if x.contains("SUCCESSFULLY INSTALLED") + || x.starts_with("INSTALLED WITH WARNINGS") => + { + break; + } + + // Install + x if x.starts_with("Install") => { + stdin + .write_all("\n".as_bytes()) + .expect("Failed to write to stdin"); + } + x if x.starts_with("[I]nstall") => { + stdin + .write_all("I\n".as_bytes()) + .expect("Failed to write to stdin"); + log::debug!("Installing"); + } + x if x.to_ascii_lowercase().starts_with("[r]e-install") => { + stdin + .write_all("Q\n".as_bytes()) + .expect("Could not quit out"); + log::debug!("Continue as already installed"); + break; + } + _ => {} } + } else { + break; + } + } + + match child.wait_with_output() { + Ok(output) if !output.status.success() => { + panic!("{:#?}", output); + } + Err(err) => { + panic!("Did not close properly: {}", err); } - Err(error) => { - log::error!("Command did not gracefully terminate, {}", error); - panic!(); + Ok(output) => { + log::trace!("{:#?}", output); } - _ => {} } }