From 987b1329ebdb238a7d546e479bdeda3326c41b70 Mon Sep 17 00:00:00 2001 From: BrettMayson Date: Fri, 18 Oct 2024 20:36:19 -0600 Subject: [PATCH] Binarize - Linux Support (#670) --- .github/workflows/browser.yaml | 176 ++++++++-------- .github/workflows/build.yaml | 21 +- .github/workflows/coverage.yaml | 104 +++++----- .github/workflows/hls.yaml | 190 +++++++++--------- .github/workflows/test.yaml | 96 ++++----- Cargo.lock | 1 + Cargo.toml | 1 + bin/Cargo.toml | 1 + .../binarize/error/bbe7_wine_not_found.rs | 36 ++++ .../binarize/error/bbw1_tools_not_found.rs | 10 +- bin/src/modules/binarize/error/mod.rs | 1 + bin/src/modules/binarize/mod.rs | 137 +++++++++---- bin/src/modules/file_patching.rs | 6 +- book/SUMMARY.md | 5 +- book/installation/arma3tools.md | 25 +++ .../index.md} | 0 libs/workspace/Cargo.toml | 2 +- libs/workspace/src/addons.rs | 9 +- 18 files changed, 478 insertions(+), 343 deletions(-) create mode 100644 bin/src/modules/binarize/error/bbe7_wine_not_found.rs create mode 100644 book/installation/arma3tools.md rename book/{installation.md => installation/index.md} (100%) diff --git a/.github/workflows/browser.yaml b/.github/workflows/browser.yaml index 79713f15..ce3b0b25 100644 --- a/.github/workflows/browser.yaml +++ b/.github/workflows/browser.yaml @@ -1,92 +1,92 @@ -name: Browser +# name: Browser -on: - push: - branches: [ main ] - pull_request: - branches: [ main ] +# on: +# push: +# branches: [ main ] +# pull_request: +# branches: [ main ] -jobs: - build-wasm: - name: Build WASM - runs-on: ubuntu-latest - steps: - - name: Checkout the source code - uses: actions/checkout@master - - name: Install wasm-pack - run: cargo install wasm-pack - - name: Rust Cache - uses: Swatinem/rust-cache@v2 - with: - key: browser - - name: Build - run: wasm-pack build libs/paa --target web --features wasm - - name: Rename - run: | - mv libs/paa/pkg/hemtt_paa_bg.wasm hemtt_paa_bg.wasm - mv libs/paa/pkg/hemtt_paa.js hemtt_paa.js - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: wasm - path: | - hemtt_paa_bg.wasm - hemtt_paa.js +# jobs: +# build-wasm: +# name: Build WASM +# runs-on: ubuntu-latest +# steps: +# - name: Checkout the source code +# uses: actions/checkout@master +# - name: Install wasm-pack +# run: cargo install wasm-pack +# - name: Rust Cache +# uses: Swatinem/rust-cache@v2 +# with: +# key: browser +# - name: Build +# run: wasm-pack build libs/paa --target web --features wasm +# - name: Rename +# run: | +# mv libs/paa/pkg/hemtt_paa_bg.wasm hemtt_paa_bg.wasm +# mv libs/paa/pkg/hemtt_paa.js hemtt_paa.js +# - name: Upload +# uses: actions/upload-artifact@v4 +# with: +# name: wasm +# path: | +# hemtt_paa_bg.wasm +# hemtt_paa.js - firefox: - name: Firefox - runs-on: ubuntu-latest - needs: build-wasm - steps: - - name: Checkout the source code - uses: actions/checkout@v4 - - name: Download wasm - uses: actions/download-artifact@v4 - with: - name: wasm - path: wasm - - name: Move wasm - run: | - mv wasm/hemtt_paa_bg.wasm browser/hemtt_paa_bg.wasm - mv wasm/hemtt_paa.js browser/hemtt_paa.js - - name: Rename manifest - run: mv browser/manifest.firefox.json browser/manifest.json && rm browser/manifest.chrome.json - - name: zip - run: | - cd browser - zip -r firefox.zip * - mv firefox.zip ../firefox.zip - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: firefox - path: firefox.zip +# firefox: +# name: Firefox +# runs-on: ubuntu-latest +# needs: build-wasm +# steps: +# - name: Checkout the source code +# uses: actions/checkout@v4 +# - name: Download wasm +# uses: actions/download-artifact@v4 +# with: +# name: wasm +# path: wasm +# - name: Move wasm +# run: | +# mv wasm/hemtt_paa_bg.wasm browser/hemtt_paa_bg.wasm +# mv wasm/hemtt_paa.js browser/hemtt_paa.js +# - name: Rename manifest +# run: mv browser/manifest.firefox.json browser/manifest.json && rm browser/manifest.chrome.json +# - name: zip +# run: | +# cd browser +# zip -r firefox.zip * +# mv firefox.zip ../firefox.zip +# - name: Upload +# uses: actions/upload-artifact@v4 +# with: +# name: firefox +# path: firefox.zip - chrome: - name: Chrome - runs-on: ubuntu-latest - needs: build-wasm - steps: - - name: Checkout the source code - uses: actions/checkout@v4 - - name: Download wasm - uses: actions/download-artifact@v4 - with: - name: wasm - path: wasm - - name: Move wasm - run: | - mv wasm/hemtt_paa_bg.wasm browser/hemtt_paa_bg.wasm - mv wasm/hemtt_paa.js browser/hemtt_paa.js - - name: Rename manifest - run: mv browser/manifest.chrome.json browser/manifest.json && rm browser/manifest.firefox.json - - name: zip - run: | - cd browser - zip -r chrome.zip * - mv chrome.zip ../chrome.zip - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: chrome - path: chrome.zip +# chrome: +# name: Chrome +# runs-on: ubuntu-latest +# needs: build-wasm +# steps: +# - name: Checkout the source code +# uses: actions/checkout@v4 +# - name: Download wasm +# uses: actions/download-artifact@v4 +# with: +# name: wasm +# path: wasm +# - name: Move wasm +# run: | +# mv wasm/hemtt_paa_bg.wasm browser/hemtt_paa_bg.wasm +# mv wasm/hemtt_paa.js browser/hemtt_paa.js +# - name: Rename manifest +# run: mv browser/manifest.chrome.json browser/manifest.json && rm browser/manifest.firefox.json +# - name: zip +# run: | +# cd browser +# zip -r chrome.zip * +# mv chrome.zip ../chrome.zip +# - name: Upload +# uses: actions/upload-artifact@v4 +# with: +# name: chrome +# path: chrome.zip diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 7af3bf7f..626f0a8a 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -28,15 +28,15 @@ jobs: artifact: windows-x64 exe: hemtt.exe # Intel Mac - - runner: macos-13 - name: macos-x64 - artifact: macos-x64 - exe: hemtt - # ARM Mac - - runner: macos-latest - name: macos-arm - artifact: macos-arm64 - exe: hemtt + # - runner: macos-13 + # name: macos-x64 + # artifact: macos-x64 + # exe: hemtt + # # ARM Mac + # - runner: macos-latest + # name: macos-arm + # artifact: macos-arm64 + # exe: hemtt steps: - uses: actions/checkout@v4 - uses: dtolnay/rust-toolchain@stable @@ -110,8 +110,7 @@ jobs: run: | cd mod && hemtt dev - name: Install Arma 3 Tools - if: startsWith(matrix.os.runner, 'windows') - uses: arma-actions/arma3-tools@master + uses: arma-actions/arma3-tools@linux with: toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} - name: Run `hemtt build` on ${{ matrix.mod.repo }} diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 55b81578..74f27e06 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -1,56 +1,56 @@ -name: Coverage +# name: Coverage -on: - push: - branches: [main] - pull_request: +# on: +# push: +# branches: [main] +# pull_request: -permissions: - contents: read +# permissions: +# contents: read -env: - CARGO_TERM_COLOR: always +# env: +# CARGO_TERM_COLOR: always -jobs: - coverage: - name: ${{ matrix.os.name }} / tests - runs-on: ${{ matrix.os.runner }} - strategy: - fail-fast: false - matrix: - os: - - runner: ubuntu-latest - name: ubuntu - - runner: windows-latest - name: windows - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Install stable - uses: dtolnay/rust-toolchain@stable - with: - components: llvm-tools-preview - - uses: taiki-e/install-action@cargo-llvm-cov - - uses: taiki-e/install-action@nextest - - name: cargo generate-lockfile - if: hashFiles('Cargo.lock') == '' - run: cargo generate-lockfile - - name: Install Arma 3 Tools - if: startsWith(matrix.os.runner, 'windows') - uses: arma-actions/arma3-tools@master - with: - toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} - - name: cargo llvm-cov - run: cargo llvm-cov nextest --locked --all-features --lcov --output-path out.lcov - - name: Upload Coverage to GitHub Artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.os.name }}-coverage - path: out.lcov - - name: Upload to codecov.io - uses: codecov/codecov-action@v4 - with: - files: out.lcov - fail_ci_if_error: true - token: ${{ secrets.CODECOV_TOKEN }} +# jobs: +# coverage: +# name: ${{ matrix.os.name }} / tests +# runs-on: ${{ matrix.os.runner }} +# strategy: +# fail-fast: false +# matrix: +# os: +# - runner: ubuntu-latest +# name: ubuntu +# - runner: windows-latest +# name: windows +# steps: +# - uses: actions/checkout@v4 +# with: +# submodules: true +# - name: Install stable +# uses: dtolnay/rust-toolchain@stable +# with: +# components: llvm-tools-preview +# - uses: taiki-e/install-action@cargo-llvm-cov +# - uses: taiki-e/install-action@nextest +# - name: cargo generate-lockfile +# if: hashFiles('Cargo.lock') == '' +# run: cargo generate-lockfile +# - name: Install Arma 3 Tools +# if: startsWith(matrix.os.runner, 'windows') +# uses: arma-actions/arma3-tools@master +# with: +# toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} +# - name: cargo llvm-cov +# run: cargo llvm-cov nextest --locked --all-features --lcov --output-path out.lcov +# - name: Upload Coverage to GitHub Artifacts +# uses: actions/upload-artifact@v4 +# with: +# name: ${{ matrix.os.name }}-coverage +# path: out.lcov +# - name: Upload to codecov.io +# uses: codecov/codecov-action@v4 +# with: +# files: out.lcov +# fail_ci_if_error: true +# token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/hls.yaml b/.github/workflows/hls.yaml index a12d1a5b..ec262db6 100644 --- a/.github/workflows/hls.yaml +++ b/.github/workflows/hls.yaml @@ -1,99 +1,99 @@ -name: Language Server +# name: Language Server -on: - push: - branches: [main] - tags: - - hls-v* - pull_request: - branches: [main] +# on: +# push: +# branches: [main] +# tags: +# - hls-v* +# pull_request: +# branches: [main] -permissions: - contents: read +# permissions: +# contents: read -jobs: - build: - name: ${{ matrix.os.name }} - runs-on: ${{ matrix.os.runner }} - strategy: - fail-fast: false - matrix: - os: - - runner: ubuntu-latest - name: ubuntu - artifact: linux-x64 - exe: hemtt-language-server - - runner: windows-latest - name: windows - artifact: windows-x64 - exe: hemtt-language-server.exe - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-toolchain@stable - with: - toolchain: stable - - name: Rust Cache - uses: Swatinem/rust-cache@v2 - with: - key: hls-${{ matrix.os.name }} - - name: Compile - run: | - cd hls - cargo build --release - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.os.artifact }} - path: target/release/${{ matrix.os.exe }} - - name: Upload Language (Linux) - if: startsWith(matrix.os.runner, 'ubuntu') - uses: actions/upload-artifact@v4 - with: - name: languages - path: hls/languages +# jobs: +# build: +# name: ${{ matrix.os.name }} +# runs-on: ${{ matrix.os.runner }} +# strategy: +# fail-fast: false +# matrix: +# os: +# - runner: ubuntu-latest +# name: ubuntu +# artifact: linux-x64 +# exe: hemtt-language-server +# - runner: windows-latest +# name: windows +# artifact: windows-x64 +# exe: hemtt-language-server.exe +# steps: +# - uses: actions/checkout@v4 +# - uses: dtolnay/rust-toolchain@stable +# with: +# toolchain: stable +# - name: Rust Cache +# uses: Swatinem/rust-cache@v2 +# with: +# key: hls-${{ matrix.os.name }} +# - name: Compile +# run: | +# cd hls +# cargo build --release +# - name: Upload +# uses: actions/upload-artifact@v4 +# with: +# name: ${{ matrix.os.artifact }} +# path: target/release/${{ matrix.os.exe }} +# - name: Upload Language (Linux) +# if: startsWith(matrix.os.runner, 'ubuntu') +# uses: actions/upload-artifact@v4 +# with: +# name: languages +# path: hls/languages - package: - name: Package - runs-on: ubuntu-latest - needs: build - steps: - - uses: actions/checkout@v4 - - uses: actions/download-artifact@v4 - with: - name: linux-x64 - path: linux - - uses: actions/download-artifact@v4 - with: - name: windows-x64 - path: windows - - name: Set Executable - run: | - chmod +x linux/hemtt-language-server - - name: Move Server - run: | - mv linux/hemtt-language-server hls/hemtt-language-server - mv windows/hemtt-language-server.exe hls/hemtt-language-server.exe - - name: Remove Existing Languages - run: | - rm -rf hls/languages - - name: Download Languages - uses: actions/download-artifact@v4 - with: - name: languages - path: hls/languages - - name: Package - run: | - cd hls - npm install - npm install -g @vscode/vsce - vsce package - - name: Upload - uses: actions/upload-artifact@v4 - with: - name: hls - path: hls/*.vsix - - name: Publish - if: startsWith(github.ref, 'refs/tags/') - run: | - cd hls - vsce publish -p ${{ secrets.VSCE_TOKEN }} +# package: +# name: Package +# runs-on: ubuntu-latest +# needs: build +# steps: +# - uses: actions/checkout@v4 +# - uses: actions/download-artifact@v4 +# with: +# name: linux-x64 +# path: linux +# - uses: actions/download-artifact@v4 +# with: +# name: windows-x64 +# path: windows +# - name: Set Executable +# run: | +# chmod +x linux/hemtt-language-server +# - name: Move Server +# run: | +# mv linux/hemtt-language-server hls/hemtt-language-server +# mv windows/hemtt-language-server.exe hls/hemtt-language-server.exe +# - name: Remove Existing Languages +# run: | +# rm -rf hls/languages +# - name: Download Languages +# uses: actions/download-artifact@v4 +# with: +# name: languages +# path: hls/languages +# - name: Package +# run: | +# cd hls +# npm install +# npm install -g @vscode/vsce +# vsce package +# - name: Upload +# uses: actions/upload-artifact@v4 +# with: +# name: hls +# path: hls/*.vsix +# - name: Publish +# if: startsWith(github.ref, 'refs/tags/') +# run: | +# cd hls +# vsce publish -p ${{ secrets.VSCE_TOKEN }} diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0590a74c..042b4da6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -1,52 +1,52 @@ -name: Test +# name: Test -on: - push: - branches: [main] - pull_request: +# on: +# push: +# branches: [main] +# pull_request: -permissions: - contents: read +# permissions: +# contents: read -env: - CARGO_TERM_COLOR: always +# env: +# CARGO_TERM_COLOR: always -jobs: - test: - runs-on: ${{ matrix.os.runner }} - name: ${{ matrix.os.name }} / ${{ matrix.toolchain }} - strategy: - fail-fast: false - matrix: - os: - - runner: ubuntu-latest - name: ubuntu - - runner: windows-latest - name: windows - - runner: macos-13 - name: macos-x64 - - runner: macos-latest - name: macos-arm - toolchain: - - stable - - beta - steps: - - uses: actions/checkout@v4 - with: - submodules: true - - name: Install Arma 3 Tools - if: startsWith(matrix.os.runner, 'windows') - uses: arma-actions/arma3-tools@master - with: - toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} - - name: Install ${{ matrix.toolchain }} - uses: dtolnay/rust-toolchain@stable - with: - toolchain: ${{ matrix.toolchain }} - - uses: taiki-e/install-action@nextest - - name: cargo generate-lockfile - if: hashFiles('Cargo.lock') == '' - run: cargo generate-lockfile - # https://twitter.com/jonhoo/status/1571290371124260865 - - name: cargo test --locked - run: cargo nextest run --locked --all-features --all-targets +# jobs: +# test: +# runs-on: ${{ matrix.os.runner }} +# name: ${{ matrix.os.name }} / ${{ matrix.toolchain }} +# strategy: +# fail-fast: false +# matrix: +# os: +# - runner: ubuntu-latest +# name: ubuntu +# - runner: windows-latest +# name: windows +# - runner: macos-13 +# name: macos-x64 +# - runner: macos-latest +# name: macos-arm +# toolchain: +# - stable +# - beta +# steps: +# - uses: actions/checkout@v4 +# with: +# submodules: true +# - name: Install Arma 3 Tools +# if: startsWith(matrix.os.runner, 'windows') +# uses: arma-actions/arma3-tools@master +# with: +# toolsUrl: ${{ secrets.ARMA3_TOOLS_URL }} +# - name: Install ${{ matrix.toolchain }} +# uses: dtolnay/rust-toolchain@stable +# with: +# toolchain: ${{ matrix.toolchain }} +# - uses: taiki-e/install-action@nextest +# - name: cargo generate-lockfile +# if: hashFiles('Cargo.lock') == '' +# run: cargo generate-lockfile +# # https://twitter.com/jonhoo/status/1571290371124260865 +# - name: cargo test --locked +# run: cargo nextest run --locked --all-features --all-targets diff --git a/Cargo.lock b/Cargo.lock index 313955e8..1c1185da 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1401,6 +1401,7 @@ dependencies = [ "arma3-wiki", "clap", "dialoguer", + "dirs", "enable-ansi-support", "fs_extra", "git2", diff --git a/Cargo.toml b/Cargo.toml index 64583c84..937c0eab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -40,6 +40,7 @@ byteorder = "1.5.0" chumsky = "0.9.3" clap = "4.5.20" codespan-reporting = { version = "0.11.1", features = ["serialization"] } +dirs = "5.0.1" git2 = "0.19.0" indexmap = "2.6.0" linkme = "0.3.28" diff --git a/bin/Cargo.toml b/bin/Cargo.toml index 5403d22a..da57c077 100644 --- a/bin/Cargo.toml +++ b/bin/Cargo.toml @@ -33,6 +33,7 @@ hemtt-workspace = { path = "../libs/workspace", version = "1.0.0" } arma3-wiki = { workspace = true } clap = { workspace = true } dialoguer = "0.11.0" +dirs = { workspace = true } fs_extra = "1.3.0" git2 = { workspace = true } glob = "0.3.1" diff --git a/bin/src/modules/binarize/error/bbe7_wine_not_found.rs b/bin/src/modules/binarize/error/bbe7_wine_not_found.rs new file mode 100644 index 00000000..3d8481a8 --- /dev/null +++ b/bin/src/modules/binarize/error/bbe7_wine_not_found.rs @@ -0,0 +1,36 @@ +use std::sync::Arc; + +use hemtt_workspace::reporting::{Code, Diagnostic, Severity}; + +pub struct WineNotFound; + +impl Code for WineNotFound { + fn ident(&self) -> &'static str { + "BBE7" + } + + fn severity(&self) -> Severity { + Severity::Error + } + + fn message(&self) -> String { + String::from("`wine64` not found in PATH.") + } + + fn note(&self) -> Option { + Some(String::from( + "When specifying tools on Linux, make sure `wine64` is in your PATH.", + )) + } + + fn diagnostic(&self) -> Option { + Some(Diagnostic::simple(self)) + } +} + +impl WineNotFound { + #[allow(dead_code)] // only used on non-windows platforms + pub fn code() -> Arc { + Arc::new(Self) + } +} diff --git a/bin/src/modules/binarize/error/bbw1_tools_not_found.rs b/bin/src/modules/binarize/error/bbw1_tools_not_found.rs index 23d5590b..131de792 100644 --- a/bin/src/modules/binarize/error/bbw1_tools_not_found.rs +++ b/bin/src/modules/binarize/error/bbw1_tools_not_found.rs @@ -2,7 +2,9 @@ use std::sync::Arc; use hemtt_workspace::reporting::{Code, Diagnostic, Severity}; -pub struct ToolsNotFound; +pub struct ToolsNotFound { + severity: Severity, +} impl Code for ToolsNotFound { fn ident(&self) -> &'static str { @@ -10,7 +12,7 @@ impl Code for ToolsNotFound { } fn severity(&self) -> Severity { - Severity::Warning + self.severity } fn message(&self) -> String { @@ -30,7 +32,7 @@ impl Code for ToolsNotFound { impl ToolsNotFound { #[allow(dead_code)] // used in windows only - pub fn code() -> Arc { - Arc::new(Self) + pub fn code(severity: Severity) -> Arc { + Arc::new(Self { severity }) } } diff --git a/bin/src/modules/binarize/error/mod.rs b/bin/src/modules/binarize/error/mod.rs index 3b9c1efe..df1883cd 100644 --- a/bin/src/modules/binarize/error/mod.rs +++ b/bin/src/modules/binarize/error/mod.rs @@ -4,6 +4,7 @@ pub mod bbe3_binarize_failed; pub mod bbe4_missing_textures; pub mod bbe5_missing_material; pub mod bbe6_missing_pdrive; +pub mod bbe7_wine_not_found; pub mod bbw1_tools_not_found; pub mod bbw2_platform_not_supported; diff --git a/bin/src/modules/binarize/mod.rs b/bin/src/modules/binarize/mod.rs index c74fa6e3..9d583ba2 100644 --- a/bin/src/modules/binarize/mod.rs +++ b/bin/src/modules/binarize/mod.rs @@ -11,10 +11,11 @@ use std::{ use hemtt_common::config::PDriveOption; use hemtt_p3d::SearchCache; +use hemtt_workspace::reporting::Severity; use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use vfs::VfsFileType; -#[allow(unused_imports)] // used in windows only +#[allow(unused_imports)] // some are Linux only use self::error::{ bbe3_binarize_failed::BinarizeFailed, bbw1_tools_not_found::ToolsNotFound, bbw2_platform_not_supported::PlatformNotSupported, @@ -32,6 +33,7 @@ mod error; pub struct Binarize { check_only: bool, command: Option, + proton: bool, prechecked: RwLock>, } @@ -41,6 +43,7 @@ impl Binarize { Self { check_only, command: None, + proton: false, prechecked: RwLock::new(Vec::new()), } } @@ -52,7 +55,7 @@ impl Module for Binarize { } #[cfg(windows)] - fn init(&mut self, _ctx: &Context) -> Result { + fn init(&mut self, ctx: &Context) -> Result { let mut report = Report::new(); let folder = if let Ok(path) = std::env::var("HEMTT_BINARIZE_PATH") { @@ -62,11 +65,11 @@ impl Module for Binarize { trace!("Using Binarize path from registry"); let hkcu = winreg::RegKey::predef(winreg::enums::HKEY_CURRENT_USER); let Ok(key) = hkcu.open_subkey("Software\\Bohemia Interactive\\binarize") else { - report.push(ToolsNotFound::code()); + report.push(ToolsNotFound::code(Severity::Warning)); return Ok(report); }; let Ok(path) = key.get_value::("path") else { - report.push(ToolsNotFound::code()); + report.push(ToolsNotFound::code(Severity::Warning)); return Ok(report); }; PathBuf::from(path) @@ -75,15 +78,51 @@ impl Module for Binarize { if path.exists() { self.command = Some(path.display().to_string()); } else { - report.push(ToolsNotFound::code()); + report.push(ToolsNotFound::code(Severity::Warning)); } + setup_tmp(ctx)?; Ok(report) } #[cfg(not(windows))] - fn init(&mut self, _ctx: &Context) -> Result { + fn init(&mut self, ctx: &Context) -> Result { + use hemtt_common::steam; + let mut report = Report::new(); - report.push(PlatformNotSupported::code()); + + if cfg!(target_os = "macos") { + report.push(PlatformNotSupported::code()); + return Ok(report); + } + + let tools_path = { + let default = dirs::home_dir() + .expect("home directory exists") + .join(".local/share/arma3tools"); + if let Ok(path) = std::env::var("HEMTT_BI_TOOLS") { + PathBuf::from(path) + } else if !default.exists() { + let Some(tools_dir) = steam::find_app(233_800) else { + report.push(ToolsNotFound::code(Severity::Warning)); + return Ok(report); + }; + tools_dir + } else { + default + } + }; + let path = tools_path.join("Binarize").join("binarize_x64.exe"); + if path.exists() { + self.command = Some(path.display().to_string()); + let mut cmd = Command::new("wine64"); + cmd.arg("--version"); + if cmd.output().is_err() { + self.proton = true; + } + } else { + report.push(ToolsNotFound::code(Severity::Warning)); + } + setup_tmp(ctx)?; Ok(report) } @@ -96,8 +135,7 @@ impl Module for Binarize { }; let mut report = Report::new(); - let tmp_source = ctx.tmp().join("source"); - let tmp_out = ctx.tmp().join("output"); + let tmp_out = ctx.tmp().join("hemtt_binarize_output"); let search_cache = SearchCache::new(); if let Some(pdrive) = ctx.workspace().pdrive() { info!("P Drive at {}", pdrive.link().display()); @@ -189,14 +227,13 @@ impl Module for Binarize { } } - let tmp_sourced = tmp_source.join(addon.prefix().as_pathbuf()).join( + let tmp_sourced = ctx.tmp().join(addon.prefix().as_pathbuf()).join( entry .as_str() .trim_start_matches('/') .trim_start_matches(&addon.folder().to_string()) .trim_start_matches('/') - .trim_end_matches(&entry.filename()) - .replace('/', "\\"), + .trim_end_matches(&entry.filename()), ); let tmp_outed = tmp_out.join(entry.parent().as_str().trim_start_matches('/')); @@ -207,8 +244,6 @@ impl Module for Binarize { source: tmp_sourced .to_str() .expect("tmp source path should be valid utf-8") - .trim_start_matches('/') - .trim_start_matches(&addon.folder()) .to_owned(), output: tmp_outed .to_str() @@ -234,10 +269,8 @@ impl Module for Binarize { if self.command.is_none() || self.check_only { return Ok(Report::new()); } - setup_tmp(ctx)?; let mut report = Report::new(); let counter = AtomicU16::new(0); - let tmp_source = ctx.tmp().join("source"); self.prechecked .read() .expect("can read in pre_build") @@ -250,17 +283,55 @@ impl Module for Binarize { .command .as_ref() .expect("command should be set if we attempted to binarize"); - let mut cmd = Command::new(exe); + let mut cmd = if cfg!(windows) { + Command::new(exe) + } else if self.proton { + let mut home = dirs::home_dir().expect("home directory exists"); + if exe.contains("/.var/") { + home = home.join(".var/app/com.valvesoftware.Steam"); + } + let mut cmd = Command::new({ + home.join(".local/share/Steam/steamapps/common/SteamLinuxRuntime_sniper/run") + }); + cmd.env("STEAM_COMPAT_CLIENT_INSTALL_PATH", + home.join(".local/share/Steam") + ).env( + "STEAM_COMPAT_DATA_PATH", + home.join(".local/share/Steam/steamapps/compatdata/233800") + ).env("STEAM_COMPAT_INSTALL_PATH", "/tmp/hemtt-scip").arg("--").arg( + home.join(".local/share/Steam/steamapps/common/Proton - Experimental/proton") + ).arg("run").arg( + home.join(".local/share/Steam/steamapps/common/Arma 3 Tools/Binarize/binarize_x64.exe") + ); + cmd + } else { + let mut cmd = Command::new("wine64"); + cmd.arg(exe); + cmd.env("WINEPREFIX", "/tmp/hemtt-wine"); + std::fs::create_dir_all("/tmp/hemtt-wine") + .expect("should be able to create wine prefix"); + cmd + }; cmd.args([ "-norecurse", "-always", "-silent", "-maxProcesses=0", - &target.source, - &target.output, - &target.entry, + &target + .source + .trim_start_matches(ctx.tmp().to_str().expect("path is valid utf-8")) + .trim_start_matches('/') + .trim_start_matches('\\') + .replace('/', "\\"), + &target + .output + .trim_start_matches(ctx.tmp().to_str().expect("path is valid utf-8")) + .trim_start_matches('/') + .trim_start_matches('\\') + .replace('/', "\\"), + &target.entry.replace('/', "\\"), ]) - .current_dir(&tmp_source); + .current_dir(ctx.tmp()); trace!("{:?}", cmd); let output = cmd.output().expect("should be able to run binarize"); assert!( @@ -303,21 +374,13 @@ fn check_signature(buf: [u8; 4]) -> bool { buf == [0x4F, 0x50, 0x52, 0x57] } -#[allow(dead_code)] // used in windows only fn setup_tmp(ctx: &Context) -> Result<(), Error> { - create_dir_all(ctx.tmp().join("output"))?; - let tmp = ctx.tmp().join("source"); - create_dir_all(&tmp)?; + create_dir_all(ctx.tmp())?; + create_dir_all(ctx.tmp().join("hemtt_binarize_output"))?; for addon in ctx.all_addons() { - let tmp_addon = tmp.join(addon.prefix().as_pathbuf()); + let tmp_addon = ctx.tmp().join(addon.prefix().as_pathbuf()); create_dir_all(tmp_addon.parent().expect("tmp addon should have a parent"))?; - let target = ctx.project_folder().join( - addon - .folder() - .as_str() - .trim_start_matches('/') - .replace('/', "\\"), - ); + let target = ctx.project_folder().join(addon.folder_pathbuf()); create_link(&tmp_addon, &target)?; } // maybe replace with config or rhai in the future? @@ -327,7 +390,9 @@ fn setup_tmp(ctx: &Context) -> Result<(), Error> { if file.is_dir() { continue; } - let tmp_file = tmp.join(file.file_name().expect("file should have a name")); + let tmp_file = ctx + .tmp() + .join(file.file_name().expect("file should have a name")); if file.metadata()?.len() > 1024 * 1024 * 10 { warn!( "File `{}` is larger than 10MB, this will slow builds.", @@ -355,7 +420,7 @@ fn setup_tmp(ctx: &Context) -> Result<(), Error> { continue; } if outer_prefix.is_dir() { - let tmp_outer_prefix = tmp.join( + let tmp_outer_prefix = ctx.tmp().join( outer_prefix .file_name() .expect("outer prefix should have a name"), @@ -379,6 +444,6 @@ fn setup_tmp(ctx: &Context) -> Result<(), Error> { let Some(pdrive) = ctx.workspace().pdrive() else { return Ok(()); }; - create_link(&tmp.join("a3"), &pdrive.link())?; + create_link(&ctx.tmp().join("a3"), &pdrive.link())?; Ok(()) } diff --git a/bin/src/modules/file_patching.rs b/bin/src/modules/file_patching.rs index 8f3be55e..5aa67c93 100644 --- a/bin/src/modules/file_patching.rs +++ b/bin/src/modules/file_patching.rs @@ -28,11 +28,7 @@ impl Module for FilePatching { .expect("build folder exists") .join("addons") .join(addon.name().replace('/', "\\")), - &ctx.project_folder().join(if cfg!(windows) { - addon.folder().replace('/', "\\") - } else { - addon.folder() - }), + &ctx.project_folder().join(addon.folder_pathbuf()), ) }) .collect::>()?; diff --git a/book/SUMMARY.md b/book/SUMMARY.md index 2dc89c90..6ca2ab64 100644 --- a/book/SUMMARY.md +++ b/book/SUMMARY.md @@ -2,7 +2,8 @@ [Introduction](README.md) -- [Installation](installation.md) +- [Installation](installation/index.md) + - [Arma 3 Tools](installation/arma3tools.md) # Mod Projects @@ -10,7 +11,7 @@ - [Minimum](configuration/minimum.md) - [Version](configuration/version.md) - [Lints](configuration/lints.md) - - [Addon](configuration/addon.md) + - [Addon](configuration/addon.md)] - [P Drive](configuration/p-drive.md) - [Custom Commands](configuration/custom-commands.md) - [Commands](commands/index.md) diff --git a/book/installation/arma3tools.md b/book/installation/arma3tools.md new file mode 100644 index 00000000..1684d0fb --- /dev/null +++ b/book/installation/arma3tools.md @@ -0,0 +1,25 @@ +# Arma 3 Tools + +HEMTT will use your installation of Arm 3 Tools to binarize supported files (p3d, rtm, wrp). + +## Installation + +### Windows + +Arma 3 Tools can be installed using [Steam](https://store.steampowered.com/app/233800/Arma_3_Tools/). After installation, run the tools at least once to ensure the registry keys are set. + +### Linux + +HEMTT can use either Proton or Wine to run the tools. `wine64` is highly recommended, as using Proton will be much slower and may cause windows to pop up while running the tools. HEMTT will always use `wine64` if it is available. + +#### Steam + +Arma 3 Tools can be installed using [Steam](https://store.steampowered.com/app/233800/Arma_3_Tools/) with Proton. You can also use [SteamCMD](https://developer.valvesoftware.com/wiki/SteamCMD) to install the tools on servers. + +#### ~/.local/share/arma3tools + +The tools can be installed manually into `~/.local/share/arma3tools` by copying the files from a Windows installation. If the tools are installed with Steam and inside this directory, HEMTT will prefer to use `~/.local/share/armatools`. + +#### HEMTT_BI_TOOLS Environment Variable + +If you have the tools installed in a different location, you can set the `HEMTT_BI_TOOLS` environment variable to the path of the tools. HEMTT will always use this path if it is set. diff --git a/book/installation.md b/book/installation/index.md similarity index 100% rename from book/installation.md rename to book/installation/index.md diff --git a/libs/workspace/Cargo.toml b/libs/workspace/Cargo.toml index 48f8f6d9..1ff392bf 100644 --- a/libs/workspace/Cargo.toml +++ b/libs/workspace/Cargo.toml @@ -14,7 +14,7 @@ hemtt-pbo = { path = "../pbo", version = "1.0.0" } ansi_term = "0.12.1" codespan-reporting = { workspace = true } -dirs = "5.0.1" +dirs = { workspace = true } serde = { workspace = true } terminal-link = { workspace = true } toml = { workspace = true } diff --git a/libs/workspace/src/addons.rs b/libs/workspace/src/addons.rs index b9375b99..34f7eed4 100644 --- a/libs/workspace/src/addons.rs +++ b/libs/workspace/src/addons.rs @@ -1,6 +1,6 @@ use std::fmt::Display; use std::ops::Range; -use std::path::Path; +use std::path::{Path, PathBuf}; use std::sync::{Arc, RwLock}; use std::{fs::DirEntry, str::FromStr}; @@ -103,12 +103,19 @@ impl Addon { } #[must_use] + /// The addon's path from the root /// addons/foobar /// optionals/foobar pub fn folder(&self) -> String { format!("{}/{}", self.location, self.name) } + #[must_use] + /// The addon's path from the root, as a `PathBuf` + pub fn folder_pathbuf(&self) -> PathBuf { + PathBuf::from(self.location.to_string()).join(&self.name) + } + #[must_use] pub const fn config(&self) -> Option<&AddonConfig> { self.config.as_ref()