From 1c660d9cfba69ac7e902c92dbcb4bdc835e84dfe Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Mon, 4 Jul 2022 21:26:44 +0200 Subject: [PATCH 01/10] chore: bump version --- Cargo.lock | 2 +- espanso/Cargo.toml | 2 +- snapcraft.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a32ff4..05f3484 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -582,7 +582,7 @@ dependencies = [ [[package]] name = "espanso" -version = "2.1.6-beta" +version = "2.1.7-beta" dependencies = [ "anyhow", "caps", diff --git a/espanso/Cargo.toml b/espanso/Cargo.toml index 3a8c270..0e507ad 100644 --- a/espanso/Cargo.toml +++ b/espanso/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "espanso" -version = "2.1.6-beta" +version = "2.1.7-beta" authors = ["Federico Terzi "] license = "GPL-3.0" description = "Cross-platform Text Expander written in Rust" diff --git a/snapcraft.yaml b/snapcraft.yaml index 3003c5d..a66fc40 100644 --- a/snapcraft.yaml +++ b/snapcraft.yaml @@ -1,5 +1,5 @@ name: espanso -version: 2.1.6-beta +version: 2.1.7-beta summary: A Cross-platform Text Expander written in Rust description: | espanso is a Cross-platform, Text Expander written in Rust. From 930bf807b5802218adff3d0a73e339233182e6dc Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Mon, 4 Jul 2022 21:48:49 +0200 Subject: [PATCH 02/10] feat: remove OpenSSL dependency on Linux #1056 (#1287) --- Cargo.lock | 121 +++++++++++++++++++++++++++++++++++++ espanso-package/Cargo.toml | 12 +++- espanso/Cargo.toml | 9 ++- scripts/build_binary.rs | 7 +++ scripts/test_binary.rs | 7 +++ 5 files changed, 153 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05f3484..cab6664 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1042,6 +1042,19 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" +[[package]] +name = "futures-macro" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote 1.0.9", + "syn 1.0.67", +] + [[package]] name = "futures-sink" version = "0.3.17" @@ -1063,10 +1076,13 @@ dependencies = [ "autocfg", "futures-core", "futures-io", + "futures-macro", "futures-task", "memchr", "pin-project-lite", "pin-utils", + "proc-macro-hack", + "proc-macro-nested", "slab", ] @@ -1246,6 +1262,21 @@ dependencies = [ "want", ] +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "futures-util", + "hyper", + "log", + "rustls", + "tokio", + "tokio-rustls", + "webpki", +] + [[package]] name = "hyper-tls" version = "0.5.0" @@ -2043,6 +2074,12 @@ version = "0.5.19" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + [[package]] name = "proc-macro2" version = "1.0.24" @@ -2297,6 +2334,7 @@ dependencies = [ "http", "http-body", "hyper", + "hyper-rustls", "hyper-tls", "ipnet", "js-sys", @@ -2306,17 +2344,35 @@ dependencies = [ "native-tls", "percent-encoding", "pin-project-lite", + "rustls", "serde", "serde_urlencoded", "tokio", "tokio-native-tls", + "tokio-rustls", "url", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg 0.7.0", ] +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi 0.3.9", +] + [[package]] name = "rust-argon2" version = "0.8.3" @@ -2329,6 +2385,19 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64", + "log", + "ring", + "sct", + "webpki", +] + [[package]] name = "ryu" version = "1.0.5" @@ -2366,6 +2435,16 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + [[package]] name = "security-framework" version = "2.3.1" @@ -2514,6 +2593,12 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "squote" version = "0.1.2" @@ -2795,6 +2880,17 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + [[package]] name = "tokio-util" version = "0.6.7" @@ -2916,6 +3012,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "url" version = "2.2.2" @@ -3145,6 +3247,25 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki", +] + [[package]] name = "widestring" version = "0.4.3" diff --git a/espanso-package/Cargo.toml b/espanso-package/Cargo.toml index 0ceeeb6..fe5d29d 100644 --- a/espanso-package/Cargo.toml +++ b/espanso-package/Cargo.toml @@ -14,11 +14,19 @@ serde_yaml = "0.8.17" tempdir = "0.3.7" glob = "0.3.0" natord = "1.0.9" -reqwest = { version = "0.11.4", features = ["blocking"] } lazy_static = "1.4.0" regex = "1.4.3" zip = "0.5.13" scopeguard = "1.1.0" fs_extra = "1.2.0" sha2 = "0.9.6" -hex = "0.4.3" \ No newline at end of file +hex = "0.4.3" +reqwest = { version = "0.11.4", features = ["blocking"], default-features = false} + +# On Linux we don't want to depend on openssl to avoid dependency issues +# https://github.com/espanso/espanso/issues/1056 +# We need to use features to control this behavior instead of targets due to this Cargo bug: +# https://github.com/rust-lang/cargo/issues/1197 +[features] +default-tls=["reqwest/default-tls"] +rustls-tls=["reqwest/rustls-tls"] \ No newline at end of file diff --git a/espanso/Cargo.toml b/espanso/Cargo.toml index 0e507ad..03f4533 100644 --- a/espanso/Cargo.toml +++ b/espanso/Cargo.toml @@ -9,7 +9,14 @@ homepage = "https://github.com/federico-terzi/espanso" edition = "2018" [features] -default = ["modulo"] +default = ["modulo", "native-tls"] + +# These features control whether Espanso will use the native TLS functionality +# or not. On some platforms (currently Linux) we prefer vendoring the SSL +# logic used by the packages to avoid dependency issues. +# https://github.com/espanso/espanso/issues/1056 +native-tls = ["espanso-package/default-tls"] +vendored-tls = ["espanso-package/rustls-tls"] # If the wayland feature is enabled, all X11 dependencies will be dropped # and only methods suitable for Wayland will be used diff --git a/scripts/build_binary.rs b/scripts/build_binary.rs index a2f98c4..1ca1201 100644 --- a/scripts/build_binary.rs +++ b/scripts/build_binary.rs @@ -53,6 +53,13 @@ fn main() { if !avoid_modulo { features.push("modulo"); } + // On linux, we don't want to rely on OpenSSL to avoid dependency issues + // https://github.com/espanso/espanso/issues/1056 + if cfg!(target_os = "linux") { + features.push("vendored-tls") + } else { + features.push("native-tls") + } let features_flag = features.join(" "); diff --git a/scripts/test_binary.rs b/scripts/test_binary.rs index 876bc5e..172165e 100644 --- a/scripts/test_binary.rs +++ b/scripts/test_binary.rs @@ -48,6 +48,13 @@ fn main() { if wayland { features.push("wayland"); } + // On linux, we don't want to rely on OpenSSL to avoid dependency issues + // https://github.com/espanso/espanso/issues/1056 + if cfg!(target_os = "linux") { + features.push("vendored-tls") + } else { + features.push("native-tls") + } let features_flag = features.join(" "); From 7fd1502bcf061c2abb0a26f86eb04233d5ff3a20 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sat, 13 Aug 2022 10:59:48 +0200 Subject: [PATCH 03/10] fix(misc): add missing feature flags in deb package build #1056 --- .github/scripts/ubuntu/build_deb.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/scripts/ubuntu/build_deb.sh b/.github/scripts/ubuntu/build_deb.sh index d2352ad..d826392 100755 --- a/.github/scripts/ubuntu/build_deb.sh +++ b/.github/scripts/ubuntu/build_deb.sh @@ -8,10 +8,10 @@ cargo install cargo-deb --version 1.34.0 cd espanso echo "Building X11 deb package" -cargo deb -p espanso +cargo deb -p espanso -- --no-default-features --features "modulo vendored-tls" echo "Building Wayland deb package" -cargo deb -p espanso --variant wayland -- --features wayland +cargo deb -p espanso --variant wayland -- --no-default-features --features "modulo wayland vendored-tls" cd .. cp espanso/target/debian/espanso_*.deb espanso-debian-x11-amd64.deb From 2ea452bf61fa1e51c0d3b81970ee12913da12dc7 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sat, 13 Aug 2022 21:53:53 +0200 Subject: [PATCH 04/10] feat(ci): add macOS codesign step (#1334) --- .github/workflows/release.yml | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 195608c..f7f468b 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -167,6 +167,20 @@ jobs: run: cargo make create-bundle --profile release env: MACOSX_DEPLOYMENT_TARGET: "10.13" + - name: Codesign executable + env: + MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} + run: | + echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain + security default-keychain -s buildespanso.keychain + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain + security import certificate.p12 -k buildespanso.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain + /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" target/mac/Espanso.app -v - name: Create ZIP archive run: | ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-Intel.zip @@ -204,17 +218,18 @@ jobs: run: cargo make create-bundle --profile release --env BUILD_ARCH=aarch64-apple-darwin - name: Codesign executable env: - MACOS_CERTIFICATE: ${{ secrets.MACOS_CERTIFICATE }} - MACOS_CERTIFICATE_PWD: ${{ secrets.MACOS_CERTIFICATE_PWD }} - MACOS_CI_KEYCHAIN_PWD: ${{ secrets.MACOS_CI_KEYCHAIN_PWD }} + MACOS_CERTIFICATE: ${{ secrets.PROD_MACOS_CERTIFICATE }} + MACOS_CERTIFICATE_PWD: ${{ secrets.PROD_MACOS_CERTIFICATE_PWD }} + MACOS_CERTIFICATE_NAME: ${{ secrets.PROD_MACOS_CERTIFICATE_NAME }} + MACOS_CI_KEYCHAIN_PWD: ${{ secrets.PROD_MACOS_CI_KEYCHAIN_PWD }} run: | echo $MACOS_CERTIFICATE | base64 --decode > certificate.p12 - security create-keychain -p $MACOS_CI_KEYCHAIN_PWD buildespanso.keychain + security create-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain security default-keychain -s buildespanso.keychain - security unlock-keychain -p $MACOS_CI_KEYCHAIN_PWD buildespanso.keychain - security import certificate.p12 -k buildespanso.keychain -P $MACOS_CERTIFICATE_PWD -T /usr/bin/codesign - security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k $MACOS_CI_KEYCHAIN_PWD buildespanso.keychain - /usr/bin/codesign --force -s "Espanso CI Self-Signed" target/mac/Espanso.app -v + security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain + security import certificate.p12 -k buildespanso.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign + security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain + /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" target/mac/Espanso.app -v - name: Create ZIP archive run: | ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-M1.zip From d795d81fbf1d0aadff62804852859be2011cc457 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Mon, 15 Aug 2022 10:22:15 +0200 Subject: [PATCH 05/10] feat(ci): add notarization step to CI (#1335) * feat(ci): add notarization step on macOS release * fix(ci): enable hardened runtime * feat(ci): remove unused code --- .github/workflows/release.yml | 38 +++++++++++++++++++++++++++++++++-- 1 file changed, 36 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index f7f468b..30f6b4c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -180,7 +180,24 @@ jobs: security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain security import certificate.p12 -k buildespanso.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain - /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" target/mac/Espanso.app -v + /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime target/mac/Espanso.app -v + - name: "Notarize executable" + env: + PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} + PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} + run: | + echo "Create keychain profile" + xcrun notarytool store-credentials "espanso-notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD" + + echo "Creating temp notarization archive" + ditto -c -k --keepParent "target/mac/Espanso.app" "notarization.zip" + + echo "Notarize app" + xcrun notarytool submit "notarization.zip" --keychain-profile "espanso-notarytool-profile" --wait + + echo "Attach staple" + xcrun stapler staple "target/mac/Espanso.app" - name: Create ZIP archive run: | ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-Intel.zip @@ -229,7 +246,24 @@ jobs: security unlock-keychain -p "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain security import certificate.p12 -k buildespanso.keychain -P "$MACOS_CERTIFICATE_PWD" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple:,codesign: -s -k "$MACOS_CI_KEYCHAIN_PWD" buildespanso.keychain - /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" target/mac/Espanso.app -v + /usr/bin/codesign --force -s "$MACOS_CERTIFICATE_NAME" --options runtime target/mac/Espanso.app -v + - name: "Notarize executable" + env: + PROD_MACOS_NOTARIZATION_APPLE_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_APPLE_ID }} + PROD_MACOS_NOTARIZATION_TEAM_ID: ${{ secrets.PROD_MACOS_NOTARIZATION_TEAM_ID }} + PROD_MACOS_NOTARIZATION_PWD: ${{ secrets.PROD_MACOS_NOTARIZATION_PWD }} + run: | + echo "Create keychain profile" + xcrun notarytool store-credentials "espanso-notarytool-profile" --apple-id "$PROD_MACOS_NOTARIZATION_APPLE_ID" --team-id "$PROD_MACOS_NOTARIZATION_TEAM_ID" --password "$PROD_MACOS_NOTARIZATION_PWD" + + echo "Creating temp notarization archive" + ditto -c -k --keepParent "target/mac/Espanso.app" "notarization.zip" + + echo "Notarize app" + xcrun notarytool submit "notarization.zip" --keychain-profile "espanso-notarytool-profile" --wait + + echo "Attach staple" + xcrun stapler staple "target/mac/Espanso.app" - name: Create ZIP archive run: | ditto -c -k --sequesterRsrc --keepParent target/mac/Espanso.app Espanso-Mac-M1.zip From ce01989f7ca36b31fd5941ceae78c3b42aaed91e Mon Sep 17 00:00:00 2001 From: Andrea Giovine Date: Mon, 15 Aug 2022 10:24:42 +0200 Subject: [PATCH 06/10] fix(ci): improve version extraction (#1336) * fix(ci): right use of grep * fix(ci): remove unnecessary `head` command --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 30f6b4c..281b6d8 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -24,7 +24,7 @@ jobs: - name: "Extract version" id: "version" run: | - ESPANSO_VERSION=$(cat espanso/Cargo.toml | grep version | head -1 | awk -F '"' '{ print $2 }') + ESPANSO_VERSION=$(grep '^version' espanso/Cargo.toml | awk -F '"' '{ print $2 }') echo version: $ESPANSO_VERSION echo "::set-output name=version::v$ESPANSO_VERSION" @@ -302,4 +302,4 @@ jobs: run: | VERSION="${{ needs.extract-version.outputs.espanso_version }}" ./scripts/publish_homebrew_version.sh - echo "Cask formula has been published here: " \ No newline at end of file + echo "Cask formula has been published here: " From ee14983f7c0b025fd9bbf1c9f775000d556a7509 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Sat, 20 Aug 2022 10:38:26 +0200 Subject: [PATCH 07/10] chore(misc): remove GitHub Sponsors link --- .github/FUNDING.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index def43b1..9998a15 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,3 @@ # These are supported funding model platforms -github: ['federico-terzi'] custom: ['https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=FHNLR5DRS267E&source=url'] From 5256e3e79f1f2772c64bbd3b726b6ae16e7f2dd9 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Thu, 25 Aug 2022 21:23:55 +0200 Subject: [PATCH 08/10] fix(misc): fix clippy warnings (#1342) * fix(misc): fix clippy warnings * fix(misc): fix clippy warnings * fix(misc): fix clippy warnings * fix(misc): fix clippy warnings * fix(misc): fix clippy warnings --- .github/workflows/ci.yml | 1 + espanso-config/src/error.rs | 2 +- espanso-config/src/legacy/config.rs | 4 +-- espanso-config/src/legacy/model.rs | 2 +- .../src/matches/group/loader/yaml/parse.rs | 2 +- espanso-config/src/matches/store/mod.rs | 2 +- espanso-detect/src/event.rs | 16 ++++++------ espanso-detect/src/hotkey/keys.rs | 2 +- espanso-detect/src/hotkey/mod.rs | 2 +- espanso-engine/src/event/effect.rs | 6 ++--- espanso-engine/src/event/external.rs | 2 +- espanso-engine/src/event/input.rs | 16 ++++++------ espanso-engine/src/event/internal.rs | 26 +++++++++---------- espanso-engine/src/event/ui.rs | 8 +++--- .../src/process/middleware/matcher.rs | 4 +-- espanso-inject/src/x11/ffi.rs | 4 +-- espanso-match/src/event.rs | 4 +-- espanso-match/src/lib.rs | 2 +- espanso-match/src/rolling/matcher.rs | 2 +- espanso-match/src/rolling/mod.rs | 4 +-- espanso-modulo/build.rs | 8 +++--- espanso-modulo/src/form/parser/layout.rs | 2 +- espanso-modulo/src/search/algorithm.rs | 13 ++++------ espanso-modulo/src/sys/search/mod.rs | 9 +++---- espanso-modulo/src/troubleshooting.rs | 4 ++- espanso-package/src/archive/mod.rs | 8 +++--- espanso-package/src/manifest.rs | 2 +- espanso-package/src/resolver.rs | 2 +- espanso-package/src/util/download.rs | 2 +- espanso-package/src/util/github.rs | 2 +- espanso-package/src/util/gitlab.rs | 2 +- espanso-render/src/extension/script.rs | 9 +++---- espanso-render/src/lib.rs | 6 ++--- espanso-render/src/renderer/util.rs | 2 +- espanso-ui/src/event.rs | 2 +- espanso/src/cli/mod.rs | 2 +- espanso/src/cli/service/linux.rs | 6 ++--- 37 files changed, 93 insertions(+), 99 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cf4b63..17c4f84 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,6 +16,7 @@ env: jobs: build: strategy: + fail-fast: false matrix: os: [windows-latest, macos-latest, ubuntu-latest] diff --git a/espanso-config/src/error.rs b/espanso-config/src/error.rs index d376013..e2b812b 100644 --- a/espanso-config/src/error.rs +++ b/espanso-config/src/error.rs @@ -64,7 +64,7 @@ impl ErrorRecord { } } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum ErrorLevel { Error, Warning, diff --git a/espanso-config/src/legacy/config.rs b/espanso-config/src/legacy/config.rs index a873744..5bb5748 100644 --- a/espanso-config/src/legacy/config.rs +++ b/espanso-config/src/legacy/config.rs @@ -386,7 +386,7 @@ impl LegacyConfig { } } -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq)] pub enum BackendType { Inject, Clipboard, @@ -740,7 +740,7 @@ impl LegacyConfigSet { } // Error handling -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] #[allow(dead_code)] pub enum ConfigLoadError { FileNotFound, diff --git a/espanso-config/src/legacy/model.rs b/espanso-config/src/legacy/model.rs index 4427deb..698ca52 100644 --- a/espanso-config/src/legacy/model.rs +++ b/espanso-config/src/legacy/model.rs @@ -21,7 +21,7 @@ use serde::{Deserialize, Serialize}; #[allow(non_camel_case_types)] #[allow(clippy::upper_case_acronyms)] -#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Eq)] pub enum KeyModifier { CTRL, SHIFT, diff --git a/espanso-config/src/matches/group/loader/yaml/parse.rs b/espanso-config/src/matches/group/loader/yaml/parse.rs index bcdfe18..32c752a 100644 --- a/espanso-config/src/matches/group/loader/yaml/parse.rs +++ b/espanso-config/src/matches/group/loader/yaml/parse.rs @@ -119,7 +119,7 @@ pub struct YAMLMatch { pub search_terms: Option>, } -#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)] +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] pub struct YAMLVariable { pub name: String, diff --git a/espanso-config/src/matches/store/mod.rs b/espanso-config/src/matches/store/mod.rs index 2c252fa..64202e9 100644 --- a/espanso-config/src/matches/store/mod.rs +++ b/espanso-config/src/matches/store/mod.rs @@ -28,7 +28,7 @@ pub trait MatchStore: Send { fn loaded_paths(&self) -> Vec; } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct MatchSet<'a> { pub matches: Vec<&'a Match>, pub global_vars: Vec<&'a Variable>, diff --git a/espanso-detect/src/event.rs b/espanso-detect/src/event.rs index 30090c5..c645e84 100644 --- a/espanso-detect/src/event.rs +++ b/espanso-detect/src/event.rs @@ -19,7 +19,7 @@ #[cfg(test)] use enum_as_inner::EnumAsInner; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] #[cfg_attr(test, derive(EnumAsInner))] pub enum InputEvent { Mouse(MouseEvent), @@ -32,7 +32,7 @@ pub enum InputEvent { AllModifiersReleased, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum MouseButton { Left, Right, @@ -44,25 +44,25 @@ pub enum MouseButton { Button5, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct MouseEvent { pub button: MouseButton, pub status: Status, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum Status { Pressed, Released, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum Variant { Left, Right, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct KeyboardEvent { pub key: Key, pub value: Option, @@ -72,7 +72,7 @@ pub struct KeyboardEvent { } // A subset of the Web's key values: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum Key { // Modifiers Alt, @@ -141,7 +141,7 @@ pub enum Key { Other(i32), } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct HotKeyEvent { pub hotkey_id: i32, } diff --git a/espanso-detect/src/hotkey/keys.rs b/espanso-detect/src/hotkey/keys.rs index fa1ccf7..c033faf 100644 --- a/espanso-detect/src/hotkey/keys.rs +++ b/espanso-detect/src/hotkey/keys.rs @@ -25,7 +25,7 @@ lazy_static! { static ref RAW_PARSER: Regex = Regex::new(r"^RAW\((\d+)\)$").unwrap(); } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq)] pub enum ShortcutKey { Alt, Control, diff --git a/espanso-detect/src/hotkey/mod.rs b/espanso-detect/src/hotkey/mod.rs index d08440b..1534a13 100644 --- a/espanso-detect/src/hotkey/mod.rs +++ b/espanso-detect/src/hotkey/mod.rs @@ -32,7 +32,7 @@ static MODIFIERS: &[ShortcutKey; 4] = &[ ShortcutKey::Meta, ]; -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq)] pub struct HotKey { pub id: i32, pub key: ShortcutKey, diff --git a/espanso-engine/src/event/effect.rs b/espanso-engine/src/event/effect.rs index 48314c1..56748f2 100644 --- a/espanso-engine/src/event/effect.rs +++ b/espanso-engine/src/event/effect.rs @@ -19,13 +19,13 @@ use super::input::Key; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct TriggerCompensationEvent { pub trigger: String, pub left_separator: Option, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct CursorHintCompensationEvent { pub cursor_hint_back_count: usize, } @@ -46,7 +46,7 @@ pub struct HtmlInjectRequest { pub html: String, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq)] pub enum TextInjectMode { Keys, Clipboard, diff --git a/espanso-engine/src/event/external.rs b/espanso-engine/src/event/external.rs index 91ae9d1..ffe80a9 100644 --- a/espanso-engine/src/event/external.rs +++ b/espanso-engine/src/event/external.rs @@ -19,7 +19,7 @@ use std::collections::HashMap; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct MatchExecRequestEvent { pub trigger: Option, pub args: HashMap, diff --git a/espanso-engine/src/event/input.rs b/espanso-engine/src/event/input.rs index fc22cf5..3577011 100644 --- a/espanso-engine/src/event/input.rs +++ b/espanso-engine/src/event/input.rs @@ -17,19 +17,19 @@ * along with espanso. If not, see . */ -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq)] pub enum Status { Pressed, Released, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq)] pub enum Variant { Left, Right, } -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq)] pub struct KeyboardEvent { pub key: Key, pub value: Option, @@ -37,7 +37,7 @@ pub struct KeyboardEvent { pub variant: Option, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum MouseButton { Left, Right, @@ -49,13 +49,13 @@ pub enum MouseButton { Button5, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct MouseEvent { pub button: MouseButton, pub status: Status, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Key { // Modifiers Alt, @@ -124,12 +124,12 @@ pub enum Key { Other(i32), } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ContextMenuClickedEvent { pub context_item_id: u32, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct HotKeyEvent { pub hotkey_id: i32, } diff --git a/espanso-engine/src/event/internal.rs b/espanso-engine/src/event/internal.rs index eac56a3..aa5b5fd 100644 --- a/espanso-engine/src/event/internal.rs +++ b/espanso-engine/src/event/internal.rs @@ -19,13 +19,13 @@ use std::collections::HashMap; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct MatchesDetectedEvent { pub matches: Vec, pub is_search: bool, } -#[derive(Debug, Clone, PartialEq, Default)] +#[derive(Debug, Clone, PartialEq, Default, Eq)] pub struct DetectedMatch { pub id: i32, pub trigger: Option, @@ -34,17 +34,17 @@ pub struct DetectedMatch { pub args: HashMap, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct MatchSelectedEvent { pub chosen: DetectedMatch, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct CauseCompensatedMatchEvent { pub m: DetectedMatch, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct RenderingRequestedEvent { pub match_id: i32, pub trigger: Option, @@ -54,38 +54,38 @@ pub struct RenderingRequestedEvent { pub format: TextFormat, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum TextFormat { Plain, Markdown, Html, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ImageRequestedEvent { pub match_id: i32, pub image_path: String, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ImageResolvedEvent { pub image_path: String, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct RenderedEvent { pub match_id: i32, pub body: String, pub format: TextFormat, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct DiscardPreviousEvent { // All Events with a source_id smaller than this one will be discarded pub minimum_source_id: u32, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct DiscardBetweenEvent { // All Events with a source_id between start_id (included) and end_id (excluded) // will be discarded @@ -93,13 +93,13 @@ pub struct DiscardBetweenEvent { pub end_id: u32, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct SecureInputEnabledEvent { pub app_name: String, pub app_path: String, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct UndoEvent { pub match_id: i32, pub trigger: String, diff --git a/espanso-engine/src/event/ui.rs b/espanso-engine/src/event/ui.rs index f23bbb9..f921050 100644 --- a/espanso-engine/src/event/ui.rs +++ b/espanso-engine/src/event/ui.rs @@ -29,7 +29,7 @@ pub enum MenuItem { Separator, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct SimpleMenuItem { pub id: u32, pub label: String, @@ -41,19 +41,19 @@ pub struct SubMenuItem { pub items: Vec, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct IconStatusChangeEvent { pub status: IconStatus, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum IconStatus { Enabled, Disabled, SecureInputDisabled, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct ShowTextEvent { pub title: String, pub text: String, diff --git a/espanso-engine/src/process/middleware/matcher.rs b/espanso-engine/src/process/middleware/matcher.rs index d16276d..8692a3b 100644 --- a/espanso-engine/src/process/middleware/matcher.rs +++ b/espanso-engine/src/process/middleware/matcher.rs @@ -44,7 +44,7 @@ pub enum MatcherEvent { VirtualSeparator, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct MatchResult { pub id: i32, pub trigger: String, @@ -104,7 +104,7 @@ impl<'a, State> Middleware for MatcherMiddleware<'a, State> { if is_event_of_interest(&event.etype) { let mut matcher_states = self.matcher_states.borrow_mut(); let prev_states = if !matcher_states.is_empty() { - matcher_states.get(matcher_states.len() - 1) + matcher_states.back() } else { None }; diff --git a/espanso-inject/src/x11/ffi.rs b/espanso-inject/src/x11/ffi.rs index c5a6cf6..d2e7f61 100644 --- a/espanso-inject/src/x11/ffi.rs +++ b/espanso-inject/src/x11/ffi.rs @@ -20,7 +20,7 @@ pub const KeyPress: c_int = 2; #[allow(non_upper_case_globals)] pub const KeyRelease: c_int = 3; -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(C)] pub struct XKeyEvent { pub type_: c_int, @@ -40,7 +40,7 @@ pub struct XKeyEvent { pub same_screen: Bool, } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[repr(C)] pub struct XModifierKeymap { pub max_keypermod: c_int, diff --git a/espanso-match/src/event.rs b/espanso-match/src/event.rs index 10a3cbb..75e37a1 100644 --- a/espanso-match/src/event.rs +++ b/espanso-match/src/event.rs @@ -17,13 +17,13 @@ * along with espanso. If not, see . */ -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Event { Key { key: Key, chars: Option }, VirtualSeparator, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Key { // Modifiers Alt, diff --git a/espanso-match/src/lib.rs b/espanso-match/src/lib.rs index f79c0a5..4dc94b4 100644 --- a/espanso-match/src/lib.rs +++ b/espanso-match/src/lib.rs @@ -26,7 +26,7 @@ pub mod regex; pub mod rolling; mod util; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct MatchResult { pub id: Id, pub trigger: String, diff --git a/espanso-match/src/rolling/matcher.rs b/espanso-match/src/rolling/matcher.rs index 44cbd99..c26fbcc 100644 --- a/espanso-match/src/rolling/matcher.rs +++ b/espanso-match/src/rolling/matcher.rs @@ -185,7 +185,7 @@ impl RollingMatcher { // in the state. if !has_previous_state { if let Some(MatcherTreeRef::Node(node)) = node.word_separators.as_ref() { - refs.extend(self.find_refs(&*node, event, true)); + refs.extend(self.find_refs(node, event, true)); } } diff --git a/espanso-match/src/rolling/mod.rs b/espanso-match/src/rolling/mod.rs index ec2db0e..c0713a2 100644 --- a/espanso-match/src/rolling/mod.rs +++ b/espanso-match/src/rolling/mod.rs @@ -23,7 +23,7 @@ pub mod matcher; mod tree; mod util; -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum RollingItem { WordSeparator, Key(Key), @@ -31,7 +31,7 @@ pub enum RollingItem { CharInsensitive(String), } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct RollingMatch { pub id: Id, pub items: Vec, diff --git a/espanso-modulo/build.rs b/espanso-modulo/build.rs index b8b889a..ba4b130 100644 --- a/espanso-modulo/build.rs +++ b/espanso-modulo/build.rs @@ -90,7 +90,7 @@ fn build_native() { ) .args(&[ "/k", - &vcvars_path.to_string_lossy().to_string(), + &vcvars_path.to_string_lossy(), "&", "nmake", "/f", @@ -320,7 +320,7 @@ fn convert_fat_libraries_to_arm(lib_dir: &Path) { // Make sure it's a fat library let lipo_output = std::process::Command::new("lipo") - .args(&["-detailed_info", &path.to_string_lossy().to_string()]) + .args(&["-detailed_info", &path.to_string_lossy()]) .output() .expect("unable to check if library is fat"); let lipo_output = String::from_utf8_lossy(&lipo_output.stdout); @@ -339,9 +339,9 @@ fn convert_fat_libraries_to_arm(lib_dir: &Path) { .args(&[ "-thin", "arm64", - &path.to_string_lossy().to_string(), + &path.to_string_lossy(), "-output", - &path.to_string_lossy().to_string(), + &path.to_string_lossy(), ]) .output() .expect("unable to extract arm64 slice from library"); diff --git a/espanso-modulo/src/form/parser/layout.rs b/espanso-modulo/src/form/parser/layout.rs index 4336b1e..9a706a5 100644 --- a/espanso-modulo/src/form/parser/layout.rs +++ b/espanso-modulo/src/form/parser/layout.rs @@ -25,7 +25,7 @@ lazy_static! { static ref FIELD_REGEX: Regex = Regex::new(r"\{\{(.*?)\}\}|\[\[(.*?)\]\]").unwrap(); } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum Token { Text(String), // Text Field(String), // id: String diff --git a/espanso-modulo/src/search/algorithm.rs b/espanso-modulo/src/search/algorithm.rs index 9faf0be..8c90e6e 100644 --- a/espanso-modulo/src/search/algorithm.rs +++ b/espanso-modulo/src/search/algorithm.rs @@ -21,11 +21,10 @@ use std::collections::HashSet; use crate::sys::search::types::SearchItem; -pub fn get_algorithm( - name: &str, - use_command_filter: bool, -) -> Box Vec> { - let search_algorithm: Box Vec> = match name { +type FilterCallback = dyn Fn(&str, &[SearchItem]) -> Vec; + +pub fn get_algorithm(name: &str, use_command_filter: bool) -> Box { + let search_algorithm: Box = match name { "exact" => Box::new(exact_match), "iexact" => Box::new(case_insensitive_exact_match), "ikey" => Box::new(case_insensitive_keyword), @@ -100,9 +99,7 @@ fn case_insensitive_keyword(query: &str, items: &[SearchItem]) -> Vec { .collect() } -fn command_filter( - search_algorithm: Box Vec>, -) -> Box Vec> { +fn command_filter(search_algorithm: Box) -> Box { Box::new(move |query, items| { let (valid_ids, trimmed_query) = if query.starts_with('>') { ( diff --git a/espanso-modulo/src/sys/search/mod.rs b/espanso-modulo/src/sys/search/mod.rs index 6ed1efe..ab0021f 100644 --- a/espanso-modulo/src/sys/search/mod.rs +++ b/espanso-modulo/src/sys/search/mod.rs @@ -147,16 +147,15 @@ mod interop { } } +type SearchAlgorithmCallback = dyn Fn(&str, &[types::SearchItem]) -> Vec; + struct SearchData { owned_search: interop::OwnedSearch, items: Vec, - algorithm: Box Vec>, + algorithm: Box, } -pub fn show( - search: types::Search, - algorithm: Box Vec>, -) -> Option { +pub fn show(search: types::Search, algorithm: Box) -> Option { use super::interop::*; let owned_search: interop::OwnedSearch = (&search).into(); diff --git a/espanso-modulo/src/troubleshooting.rs b/espanso-modulo/src/troubleshooting.rs index b19dc7d..f92c094 100644 --- a/espanso-modulo/src/troubleshooting.rs +++ b/espanso-modulo/src/troubleshooting.rs @@ -44,7 +44,9 @@ pub enum ErrorLevel { Warning, } +type OpenFileCallback = dyn Fn(&Path) + Send; + pub struct TroubleshootingHandlers { pub dont_show_again_changed: Option>, - pub open_file: Option>, + pub open_file: Option>, } diff --git a/espanso-package/src/archive/mod.rs b/espanso-package/src/archive/mod.rs index 62ae7df..aa59cce 100644 --- a/espanso-package/src/archive/mod.rs +++ b/espanso-package/src/archive/mod.rs @@ -30,7 +30,7 @@ mod util; pub const PACKAGE_SOURCE_FILE: &str = "_pkgsource.yml"; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct ArchivedPackage { // Metadata pub manifest: Manifest, @@ -39,12 +39,12 @@ pub struct ArchivedPackage { pub source: PackageSource, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct LegacyPackage { pub name: String, } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum StoredPackage { Legacy(LegacyPackage), Modern(ArchivedPackage), @@ -67,7 +67,7 @@ pub struct SaveOptions { pub overwrite_existing: bool, } -#[derive(Debug, Serialize, Deserialize, PartialEq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "snake_case")] pub enum PackageSource { Hub, diff --git a/espanso-package/src/manifest.rs b/espanso-package/src/manifest.rs index b6ff60f..e1406cd 100644 --- a/espanso-package/src/manifest.rs +++ b/espanso-package/src/manifest.rs @@ -22,7 +22,7 @@ use std::path::Path; use anyhow::{Context, Result}; use serde::{Deserialize, Serialize}; -#[derive(Debug, PartialEq, Serialize, Deserialize)] +#[derive(Debug, PartialEq, Serialize, Deserialize, Eq)] pub struct Manifest { pub name: String, pub title: String, diff --git a/espanso-package/src/resolver.rs b/espanso-package/src/resolver.rs index ceab97b..49c4801 100644 --- a/espanso-package/src/resolver.rs +++ b/espanso-package/src/resolver.rs @@ -23,7 +23,7 @@ use anyhow::{anyhow, bail, Context, Result}; use crate::manifest::Manifest; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct ResolvedPackage { pub manifest: Manifest, pub base_dir: PathBuf, diff --git a/espanso-package/src/util/download.rs b/espanso-package/src/util/download.rs index 45258a2..b1a3089 100644 --- a/espanso-package/src/util/download.rs +++ b/espanso-package/src/util/download.rs @@ -82,7 +82,7 @@ fn extract_zip(data: Vec, dest_dir: &Path) -> Result<()> { None => continue, }; - if (&*file.name()).ends_with('/') { + if file.name().ends_with('/') { std::fs::create_dir_all(&outpath)?; } else { if let Some(p) = outpath.parent() { diff --git a/espanso-package/src/util/github.rs b/espanso-package/src/util/github.rs index 69cbf8f..8528a51 100644 --- a/espanso-package/src/util/github.rs +++ b/espanso-package/src/util/github.rs @@ -28,7 +28,7 @@ lazy_static! { .unwrap(); } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct GitHubParts { author: String, name: String, diff --git a/espanso-package/src/util/gitlab.rs b/espanso-package/src/util/gitlab.rs index dbe15b7..66a2239 100644 --- a/espanso-package/src/util/gitlab.rs +++ b/espanso-package/src/util/gitlab.rs @@ -28,7 +28,7 @@ lazy_static! { .unwrap(); } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub struct GitLabParts { author: String, name: String, diff --git a/espanso-render/src/extension/script.rs b/espanso-render/src/extension/script.rs index a59c38b..663f737 100644 --- a/espanso-render/src/extension/script.rs +++ b/espanso-render/src/extension/script.rs @@ -66,16 +66,13 @@ impl Extension for ScriptExtension { // Also replace %CONFIG% and %PACKAGES% path. See issue #380 args.iter_mut().for_each(|arg| { if arg.contains("%HOME%") { - *arg = arg.replace("%HOME%", &self.home_path.to_string_lossy().to_string()); + *arg = arg.replace("%HOME%", &self.home_path.to_string_lossy()); } if arg.contains("%CONFIG%") { - *arg = arg.replace("%CONFIG%", &self.config_path.to_string_lossy().to_string()); + *arg = arg.replace("%CONFIG%", &self.config_path.to_string_lossy()); } if arg.contains("%PACKAGES%") { - *arg = arg.replace( - "%PACKAGES%", - &self.packages_path.to_string_lossy().to_string(), - ); + *arg = arg.replace("%PACKAGES%", &self.packages_path.to_string_lossy()); } // On Windows, correct paths separators diff --git a/espanso-render/src/lib.rs b/espanso-render/src/lib.rs index 29296ce..8d42cb2 100644 --- a/espanso-render/src/lib.rs +++ b/espanso-render/src/lib.rs @@ -48,7 +48,7 @@ pub struct Context<'a> { pub templates: Vec<&'a Template>, } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub struct RenderOptions { pub casing_style: CasingStyle, } @@ -61,7 +61,7 @@ impl Default for RenderOptions { } } -#[derive(Debug, Clone, PartialEq)] +#[derive(Debug, Clone, PartialEq, Eq)] pub enum CasingStyle { None, Capitalize, @@ -123,7 +123,7 @@ pub trait Extension { pub type Scope<'a> = HashMap<&'a str, ExtensionOutput>; -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum ExtensionOutput { Single(String), Multiple(HashMap), diff --git a/espanso-render/src/renderer/util.rs b/espanso-render/src/renderer/util.rs index 299e164..3152c4a 100644 --- a/espanso-render/src/renderer/util.rs +++ b/espanso-render/src/renderer/util.rs @@ -78,7 +78,7 @@ pub(crate) fn render_variables(body: &str, scope: &Scope) -> Result { ExtensionOutput::Multiple(results) => match var_subname { Some(var_subname) => { let var_subname = var_subname.as_str(); - results.get(var_subname).map_or("", |value| &*value) + results.get(var_subname).map_or("", |value| value) } None => { error!( diff --git a/espanso-ui/src/event.rs b/espanso-ui/src/event.rs index b3eb580..e344059 100644 --- a/espanso-ui/src/event.rs +++ b/espanso-ui/src/event.rs @@ -17,7 +17,7 @@ * along with espanso. If not, see . */ -#[derive(Debug, PartialEq, Clone)] +#[derive(Debug, PartialEq, Clone, Eq)] pub enum UIEvent { TrayIconClick, ContextMenuClick(u32), diff --git a/espanso/src/cli/mod.rs b/espanso/src/cli/mod.rs index 258b5a1..7e3639e 100644 --- a/espanso/src/cli/mod.rs +++ b/espanso/src/cli/mod.rs @@ -67,7 +67,7 @@ impl Default for CliModule { } } -#[derive(Debug, PartialEq)] +#[derive(Debug, PartialEq, Eq)] pub enum LogMode { Read, AppendOnly, diff --git a/espanso/src/cli/service/linux.rs b/espanso/src/cli/service/linux.rs index 53ec82e..3f464da 100644 --- a/espanso/src/cli/service/linux.rs +++ b/espanso/src/cli/service/linux.rs @@ -42,10 +42,8 @@ pub fn register() -> Result<()> { info_println!("creating service file in {:?}", service_file); let espanso_path = get_binary_path().expect("unable to get espanso executable path"); - let service_content = String::from(LINUX_SERVICE_CONTENT).replace( - "{{{espanso_path}}}", - &espanso_path.to_string_lossy().to_string(), - ); + let service_content = String::from(LINUX_SERVICE_CONTENT) + .replace("{{{espanso_path}}}", &espanso_path.to_string_lossy()); std::fs::write(service_file, service_content)?; From 8e919952e2cca85f6264dc8c0384dc79b8b2143e Mon Sep 17 00:00:00 2001 From: Jaga Santagostino Date: Thu, 25 Aug 2022 21:24:50 +0200 Subject: [PATCH 09/10] docs(misc): Fix wrong link to forms doc (#1345) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 7a23f29..903051d 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ ___ * **Custom scripts** support * **Shell commands** support * **App-specific** configurations -* Support [Forms](https://espanso.org/docs/forms/) +* Support [Forms](https://espanso.org/docs/matches/forms/) * Expandable with **packages** * Built-in **package manager** for [espanso hub](https://hub.espanso.org/) * File based configuration From b2356abe6920b60b622f20f742c768271bb89478 Mon Sep 17 00:00:00 2001 From: Federico Terzi Date: Tue, 30 Aug 2022 21:47:26 +0200 Subject: [PATCH 10/10] feat(ci): add automatic code-sign on Windows (#1352) * feat(ci): first draft of signtool script * feat(ci): add test signing step * feat: another test commit that should fail * feat: this one should succeed * fix: create installer from resources executable * fix: prevent reset of resources * fix: remove test branch --- .github/workflows/release.yml | 20 ++++- Makefile.toml | 10 +++ scripts/build_windows_installer.rs | 9 +- scripts/sign_windows_exe.rs | 138 +++++++++++++++++++++++++++++ 4 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 scripts/sign_windows_exe.rs diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 281b6d8..38d00cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -65,8 +65,24 @@ jobs: cargo install --force cargo-make --version 0.34.0 - name: Test run: cargo make test-binary --profile release - - name: Build - run: cargo make build-windows-all --profile release + - name: Build resources + run: cargo make build-windows-resources --profile release + - name: Sign resources + run: cargo make sign-windows-resources + env: + CODESIGN_PWD: ${{ secrets.WIN_CODESIGN_PWD }} + CODESIGN_CROSS_SIGNED_B64: ${{ secrets.WIN_CODESIGN_INTERMEDIATE_B64 }} + CODESIGN_CERTIFICATE_B64: ${{ secrets.WIN_CODESIGN_CERTIFICATE_B64 }} + - name: Build installer + run: cargo make build-windows-installer --profile release --skip-tasks build-windows-resources + - name: Sign installer + run: cargo make sign-windows-installer + env: + CODESIGN_PWD: ${{ secrets.WIN_CODESIGN_PWD }} + CODESIGN_CROSS_SIGNED_B64: ${{ secrets.WIN_CODESIGN_INTERMEDIATE_B64 }} + CODESIGN_CERTIFICATE_B64: ${{ secrets.WIN_CODESIGN_CERTIFICATE_B64 }} + - name: Build portable mode archive + run: cargo make build-windows-portable --profile release --skip-tasks build-windows-resources - name: Create portable mode archive shell: powershell run: | diff --git a/Makefile.toml b/Makefile.toml index 2cd02ba..e994126 100644 --- a/Makefile.toml +++ b/Makefile.toml @@ -50,6 +50,16 @@ dependencies = ["build-windows-resources"] [tasks.build-windows-all] dependencies = ["build-windows-portable", "build-windows-installer"] +[tasks.sign-windows-resources] +env = { "TARGET_SIGNTOOL_FILE" = "target/windows/resources/espansod.exe" } +script_runner = "@rust" +script = { file = "scripts/sign_windows_exe.rs" } + +[tasks.sign-windows-installer] +env = { "TARGET_SIGNTOOL_FILE" = "target/windows/installer/Espanso-Win-Installer-x86_64.exe" } +script_runner = "@rust" +script = { file = "scripts/sign_windows_exe.rs" } + # macOS [tasks.build-macos-arm-binary] diff --git a/scripts/build_windows_installer.rs b/scripts/build_windows_installer.rs index ac6969e..a23ca78 100644 --- a/scripts/build_windows_installer.rs +++ b/scripts/build_windows_installer.rs @@ -61,7 +61,7 @@ fn main() { let espanso_toml = espanso_toml_str .parse::() .expect("unable to parse Cargo.toml"); - + let arch = envmnt::get_or_panic("BUILD_ARCH"); let arch = if arch == "current" { std::env::consts::ARCH @@ -111,13 +111,10 @@ fn main() { .to_string_lossy() .to_string(), ); - iss_setup = iss_setup.replace( - "{{{output_name}}}", - &format!("{}-{}", INSTALLER_NAME, arch), - ); + iss_setup = iss_setup.replace("{{{output_name}}}", &format!("{}-{}", INSTALLER_NAME, arch)); iss_setup = iss_setup.replace( "{{{executable_path}}}", - &dunce::canonicalize(&format!("{}.exe", envmnt::get_or_panic("EXEC_PATH"))) + &dunce::canonicalize(&resources_dir.join("espansod.exe")) .unwrap() .to_string_lossy() .to_string(), diff --git a/scripts/sign_windows_exe.rs b/scripts/sign_windows_exe.rs new file mode 100644 index 0000000..7dbdea4 --- /dev/null +++ b/scripts/sign_windows_exe.rs @@ -0,0 +1,138 @@ +//! ```cargo +//! [dependencies] +//! glob = "0.3.0" +//! fs_extra = "1.2.0" +//! base64 = "0.13.0" +//! anyhow = "1.0.38" +//! ``` + +use anyhow::Result; +use std::path::PathBuf; +use std::process::Command; + +const WINDOWS_KITS_LOCATION: &str = "C:/Program Files (x86)/Windows Kits/10/bin"; +const CERTIFICATE_TARGET_DIR: &str = "target/codesign"; + +fn main() { + let _ = std::fs::remove_dir_all(CERTIFICATE_TARGET_DIR); + std::fs::create_dir_all(CERTIFICATE_TARGET_DIR).expect("unable to create target directory"); + let certificate_target_dir = PathBuf::from(CERTIFICATE_TARGET_DIR); + if !certificate_target_dir.is_dir() { + panic!("expected target directory, found none"); + } + + let signtool_path = get_signtool_location().expect("unable to locate signtool exe"); + println!("using signtool location: {:?}", signtool_path); + + let target_exe_file = + std::env::var("TARGET_SIGNTOOL_FILE").expect("TARGET_SIGNTOOL_FILE env variable not found"); + let target_exe_path = PathBuf::from(target_exe_file); + if !target_exe_path.is_file() { + panic!( + "target file '{}' cannot be found", + target_exe_path.display() + ); + } + + println!("signing file: {:?}", target_exe_path); + + let certificate_pwd = std::env::var("CODESIGN_PWD").expect("CODESIGN_PWD env variable not found"); + let cross_signed_certificate_b64 = std::env::var("CODESIGN_CROSS_SIGNED_B64") + .expect("CODESIGN_CROSS_SIGNED_B64 env variable not found"); + let codesign_certificate_b64 = std::env::var("CODESIGN_CERTIFICATE_B64") + .expect("CODESIGN_CERTIFICATE_B64 env variable not found"); + + let cross_signed_certificate = DecodedCertificate::new( + &cross_signed_certificate_b64, + certificate_target_dir.join("SectigoPublicCodeSigningRootR46_AAA.crt"), + ) + .expect("unable to decode intermediate cross-signed certificate"); + let codesign_certificate = DecodedCertificate::new( + &codesign_certificate_b64, + certificate_target_dir.join("codesign.pfx"), + ) + .expect("unable to decode codesign certificate"); + + let mut cmd = Command::new(signtool_path); + cmd.args(&[ + "sign", + "/fd", + "SHA256", + "/p", + &certificate_pwd, + "/ac", + &cross_signed_certificate.path(), + "/f", + &codesign_certificate.path(), + "/tr", + "http://timestamp.sectigo.com/rfc3161", + "/td", + "sha256", + &target_exe_path.to_string_lossy(), + ]); + + let mut handle = cmd.spawn().expect("signtool spawn failed"); + let result = handle.wait().expect("unable to read signtool exit status"); + if !result.success() { + panic!("signtool failed"); + } +} + +// Inspired by: https://github.com/dlemstra/code-sign-action/blob/main/index.ts#L143 +fn get_signtool_location() -> Option { + let mut path: Option = None; + let mut max_version = 0; + for entry in glob::glob(&format!("{}/*", WINDOWS_KITS_LOCATION)) + .expect("unable to glob windows kits location") + { + let entry = entry.expect("unable to unwrap glob entry"); + if !entry.is_dir() { + continue; + } + if !entry.to_string_lossy().ends_with(".0") { + continue; + } + let folder_name = entry.file_name().expect("unable to extract folder_name"); + let folder_version_str = folder_name.to_string_lossy().replace(".", ""); + let folder_version = folder_version_str + .parse::() + .expect("invalid folder version string"); + if folder_version > max_version { + let signtool_path_candidate = entry.join("x86").join("signtool.exe"); + if signtool_path_candidate.is_file() { + path = Some(signtool_path_candidate); + max_version = folder_version; + } + } + } + + return path; +} + +struct DecodedCertificate { + decoded_file: PathBuf, +} + +impl DecodedCertificate { + pub fn new(b64: &str, target_file: PathBuf) -> Result { + // Keys and certificates are encoded with whitespaces/newlines in them, but we need to remove them + let filtered_b64: String = b64.chars().filter(|c| !c.is_whitespace()).collect(); + let decoded = base64::decode(filtered_b64)?; + std::fs::write(&target_file, &decoded)?; + Ok(Self { + decoded_file: target_file, + }) + } + + pub fn path(&self) -> String { + self.decoded_file.to_string_lossy().to_string() + } +} + +// Delete the certificate files when they are not needed anymore +// to minimize the attack surface +impl Drop for DecodedCertificate { + fn drop(&mut self) { + std::fs::remove_file(&self.decoded_file).expect("unable to remove certificate file") + } +}