ci: add upstream update script and workflow (#73)

This commit is contained in:
Daniëlle Huisman 2025-05-16 23:40:44 +02:00 committed by GitHub
parent 8203c4232d
commit 693caab503
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 1331 additions and 283 deletions

41
.github/workflows/upstream.yml vendored Normal file
View file

@ -0,0 +1,41 @@
name: Check for upstream releases
on:
schedule:
- cron: '00 16 * * *'
workflow_dispatch: {}
jobs:
check:
name: Check for upstream releases
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Set up Rust toolchain
run: |
rustup toolchain install stable --no-self-update --profile minimal
rustup target add wasm32-unknown-unknown
- name: Set up Rust cache
uses: swatinem/rust-cache@v2
with:
cache-on-failure: true
save-if: ${{ github.ref == 'refs/heads/main' }}
- name: Install Cargo Binary Install
uses: cargo-bins/cargo-binstall@main
- name: Install crates
run: cargo binstall --force -y dioxus-cli leptosfmt yew-fmt
- name: Check for upstream releases
run: cargo run -p scripts --bin upstream
env:
GITHUB_ACTOR: ${{ env.GITHUB_ACTOR }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GIT_USER_NAME: github-actions[bot]
GIT_USER_EMAIL: github-actions[bot]@users.noreply.github.com
RUST_LOG: upstream=info

723
Cargo.lock generated
View file

@ -26,6 +26,21 @@ dependencies = [
"memchr",
]
[[package]]
name = "android-tzdata"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0"
[[package]]
name = "android_system_properties"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311"
dependencies = [
"libc",
]
[[package]]
name = "anstream"
version = "0.6.18"
@ -62,7 +77,7 @@ version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
dependencies = [
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -73,7 +88,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
dependencies = [
"anstyle",
"once_cell",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -99,6 +114,12 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c"
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "arrayref"
version = "0.3.9"
@ -267,6 +288,21 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d"
dependencies = [
"android-tzdata",
"iana-time-zone",
"js-sys",
"num-traits",
"serde",
"wasm-bindgen",
"windows-link",
]
[[package]]
name = "ciborium"
version = "0.2.2"
@ -430,6 +466,22 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "core-foundation"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b55271e5c8c478ad3f38ad24ef34923091e0548492a266d19b3c0b4d82574c63"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "core-foundation-sys"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "core_maths"
version = "0.1.1"
@ -552,6 +604,15 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c297a1c74b71ae29df00c3e22dd9534821d60eb9af5a0192823fa2acea70c2a"
[[package]]
name = "deranged"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c9e6a11ca8224451684bc0d7d5a7adbf8f2fd6887261a1cfc3c0432f9d4068e"
dependencies = [
"powerfmt",
]
[[package]]
name = "derive-where"
version = "1.4.0"
@ -1010,7 +1071,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea14ef9355e3beab063703aa9dab15afd25f0667c341310c1e5274bb1d0da18"
dependencies = [
"libc",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -1655,6 +1716,12 @@ version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
[[package]]
name = "heck"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
[[package]]
name = "hermit-abi"
version = "0.3.9"
@ -1692,6 +1759,29 @@ dependencies = [
"itoa",
]
[[package]]
name = "http-body"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
dependencies = [
"bytes",
"http 1.3.1",
]
[[package]]
name = "http-body-util"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a"
dependencies = [
"bytes",
"futures-core",
"http 1.3.1",
"http-body",
"pin-project-lite",
]
[[package]]
name = "httparse"
version = "1.10.1"
@ -1712,6 +1802,101 @@ dependencies = [
"throw_error",
]
[[package]]
name = "hyper"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.3.1",
"http-body",
"httparse",
"itoa",
"pin-project-lite",
"smallvec",
"tokio",
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.27.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2"
dependencies = [
"futures-util",
"http 1.3.1",
"hyper",
"hyper-util",
"log",
"rustls",
"rustls-native-certs",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tower-service",
]
[[package]]
name = "hyper-timeout"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b90d566bffbce6a75bd8b09a05aa8c2cb1fabb6cb348f8840c9e4c90a0d83b0"
dependencies = [
"hyper",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
[[package]]
name = "hyper-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "497bbc33a26fdd4af9ed9c70d63f61cf56a938375fbb32df34db9b1cd6d643f2"
dependencies = [
"bytes",
"futures-channel",
"futures-util",
"http 1.3.1",
"http-body",
"hyper",
"libc",
"pin-project-lite",
"socket2",
"tokio",
"tower-service",
"tracing",
]
[[package]]
name = "iana-time-zone"
version = "0.1.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0c919e5debc312ad217002b8048a17b7d83f80703865bbfcfebb0458b0b27d8"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
[[package]]
name = "iana-time-zone-haiku"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f"
dependencies = [
"cc",
]
[[package]]
name = "icu_collections"
version = "1.5.0"
@ -1899,6 +2084,16 @@ version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "71dd52191aae121e8611f1e8dc3e324dd0dd1dee1e6dd91d10ee07a3cfb4d9d8"
[[package]]
name = "iri-string"
version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
@ -1964,6 +2159,21 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonwebtoken"
version = "9.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
dependencies = [
"base64",
"js-sys",
"pem",
"ring",
"serde",
"serde_json",
"simple_asn1",
]
[[package]]
name = "keyboard-types"
version = "0.7.0"
@ -2350,12 +2560,48 @@ dependencies = [
"adler2",
]
[[package]]
name = "mio"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd"
dependencies = [
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"windows-sys 0.52.0",
]
[[package]]
name = "next_tuple"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60993920e071b0c9b66f14e2b32740a4e27ffc82854dcd72035887f336a09a28"
[[package]]
name = "num-bigint"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-integer"
version = "0.1.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
dependencies = [
"num-traits",
]
[[package]]
name = "num-traits"
version = "0.2.19"
@ -2394,6 +2640,46 @@ dependencies = [
"thiserror 1.0.69",
]
[[package]]
name = "octocrab"
version = "0.44.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86996964f8b721067b6ed238aa0ccee56ecad6ee5e714468aa567992d05d2b91"
dependencies = [
"arc-swap",
"async-trait",
"base64",
"bytes",
"cfg-if",
"chrono",
"either",
"futures",
"futures-util",
"http 1.3.1",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-timeout",
"hyper-util",
"jsonwebtoken",
"once_cell",
"percent-encoding",
"pin-project",
"secrecy",
"serde",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"snafu",
"tokio",
"tower",
"tower-http",
"tracing",
"url",
"web-time",
]
[[package]]
name = "once_cell"
version = "1.21.3"
@ -2465,6 +2751,16 @@ version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3"
[[package]]
name = "pem"
version = "3.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3"
dependencies = [
"base64",
"serde",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -2541,6 +2837,12 @@ dependencies = [
"portable-atomic",
]
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@ -2823,6 +3125,20 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "ring"
version = "0.17.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
dependencies = [
"cc",
"cfg-if",
"getrandom 0.2.16",
"libc",
"untrusted",
"windows-sys 0.52.0",
]
[[package]]
name = "roxmltree"
version = "0.20.0"
@ -2881,7 +3197,54 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "rustls"
version = "0.23.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
dependencies = [
"log",
"once_cell",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcff2dd52b58a8d98a70243663a0d234c4e2b79235637849d15913394a247d3"
dependencies = [
"openssl-probe",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pki-types"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79"
dependencies = [
"zeroize",
]
[[package]]
name = "rustls-webpki"
version = "0.103.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435"
dependencies = [
"ring",
"rustls-pki-types",
"untrusted",
]
[[package]]
@ -2923,6 +3286,15 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "schannel"
version = "0.1.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "scopeguard"
version = "1.2.0"
@ -2937,17 +3309,53 @@ dependencies = [
"env_logger",
"git2",
"log",
"octocrab",
"prettyplease",
"proc-macro2",
"quote",
"regex",
"roxmltree",
"semver",
"serde",
"serde_json",
"syn 2.0.101",
"tempfile",
"tokio",
"usvg",
]
[[package]]
name = "secrecy"
version = "0.10.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e891af845473308773346dc847b2c23ee78fe442e0472ac50e22a18a93d3ae5a"
dependencies = [
"zeroize",
]
[[package]]
name = "security-framework"
version = "3.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316"
dependencies = [
"bitflags",
"core-foundation",
"core-foundation-sys",
"libc",
"security-framework-sys",
]
[[package]]
name = "security-framework-sys"
version = "2.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
dependencies = [
"core-foundation-sys",
"libc",
]
[[package]]
name = "semver"
version = "1.0.26"
@ -3017,6 +3425,16 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59fab13f937fa393d08645bf3a84bdfe86e296747b506ada67bb15f10f218b2a"
dependencies = [
"itoa",
"serde",
]
[[package]]
name = "serde_qs"
version = "0.12.0"
@ -3197,6 +3615,27 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "signal-hook-registry"
version = "1.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9203b8055f63a2a00e2f593bb0510367fe707d7ff1e5c872de2f537b339e5410"
dependencies = [
"libc",
]
[[package]]
name = "simple_asn1"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb"
dependencies = [
"num-bigint",
"num-traits",
"thiserror 2.0.12",
"time",
]
[[package]]
name = "simplecss"
version = "0.2.2"
@ -3266,6 +3705,37 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9"
[[package]]
name = "snafu"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019"
dependencies = [
"snafu-derive",
]
[[package]]
name = "snafu-derive"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "socket2"
version = "0.5.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef"
dependencies = [
"libc",
"windows-sys 0.52.0",
]
[[package]]
name = "stable_deref_trait"
version = "1.2.0"
@ -3281,6 +3751,12 @@ dependencies = [
"float-cmp",
]
[[package]]
name = "subtle"
version = "2.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "svgtypes"
version = "0.15.3"
@ -3324,6 +3800,12 @@ dependencies = [
"syn 2.0.101",
]
[[package]]
name = "sync_wrapper"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263"
[[package]]
name = "synstructure"
version = "0.13.1"
@ -3380,7 +3862,7 @@ dependencies = [
"getrandom 0.3.2",
"once_cell",
"rustix",
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
@ -3442,6 +3924,37 @@ dependencies = [
"pin-project-lite",
]
[[package]]
name = "time"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
[[package]]
name = "time-macros"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tiny-skia-path"
version = "0.11.4"
@ -3485,7 +3998,36 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2513ca694ef9ede0fb23fe71a4ee4107cb102b9dc1930f6d0fd77aae068ae165"
dependencies = [
"backtrace",
"bytes",
"libc",
"mio",
"parking_lot",
"pin-project-lite",
"signal-hook-registry",
"socket2",
"tokio-macros",
"windows-sys 0.52.0",
]
[[package]]
name = "tokio-macros"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "tokio-rustls"
version = "0.26.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b"
dependencies = [
"rustls",
"tokio",
]
[[package]]
@ -3499,6 +4041,19 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-util"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66a539a9ad6d5d281510d5bd368c973d636c02dbf8a67300bfb6b950696ad7df"
dependencies = [
"bytes",
"futures-core",
"futures-sink",
"pin-project-lite",
"tokio",
]
[[package]]
name = "toml"
version = "0.8.22"
@ -3544,12 +4099,61 @@ dependencies = [
"winnow 0.7.10",
]
[[package]]
name = "tower"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
dependencies = [
"futures-core",
"futures-util",
"pin-project-lite",
"sync_wrapper",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-http"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fdb0c213ca27a9f57ab69ddb290fd80d970922355b83ae380b395d3986b8a2e"
dependencies = [
"bitflags",
"bytes",
"futures-util",
"http 1.3.1",
"http-body",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-layer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e"
[[package]]
name = "tower-service"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tracing"
version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
dependencies = [
"log",
"pin-project-lite",
"tracing-attributes",
"tracing-core",
@ -3597,6 +4201,12 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "try-lock"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b"
[[package]]
name = "ttf-parser"
version = "0.25.1"
@ -3704,6 +4314,12 @@ version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "untrusted"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
[[package]]
name = "url"
version = "2.5.4"
@ -3713,6 +4329,7 @@ dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
"serde",
]
[[package]]
@ -3803,6 +4420,15 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "want"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e"
dependencies = [
"try-lock",
]
[[package]]
name = "warnings"
version = "0.2.1"
@ -3934,13 +4560,92 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "web-time"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
dependencies = [
"js-sys",
"serde",
"wasm-bindgen",
]
[[package]]
name = "winapi-util"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb"
dependencies = [
"windows-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "windows-core"
version = "0.61.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46ec44dc15085cea82cf9c78f85a9114c463a369786585ad2882d1ff0b0acf40"
dependencies = [
"windows-implement",
"windows-interface",
"windows-link",
"windows-result",
"windows-strings",
]
[[package]]
name = "windows-implement"
version = "0.60.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "windows-interface"
version = "0.59.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.101",
]
[[package]]
name = "windows-link"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-result"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b895b5356fc36103d0f64dd1e94dfa7ac5633f1c9dd6e80fe9ec4adef69e09d"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-strings"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a7ab927b2637c19b3dbe0965e75d8f2d30bdd697a1516191cad2ec4df8fb28a"
dependencies = [
"windows-link",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
@ -4178,6 +4883,12 @@ dependencies = [
"synstructure",
]
[[package]]
name = "zeroize"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
[[package]]
name = "zerovec"
version = "0.10.4"

View file

@ -14,12 +14,16 @@ convert_case = "0.8.0"
env_logger = "0.11.5"
git2 = "0.20.0"
log.workspace = true
octocrab = "0.44.1"
prettyplease = "0.2.25"
proc-macro2 = "1.0.92"
quote = "1.0.37"
regex = "1.11.1"
roxmltree = "0.20.0"
semver = "1.0.26"
serde = { version = "1.0.219", features = ["derive"] }
serde_json = "1.0.140"
tempfile = "3.14.0"
tokio = { version = "1.37.0", features = ["full"] }
syn = "2.0.89"
usvg = "0.45.0"

View file

@ -1,272 +1,9 @@
use std::{collections::HashSet, error::Error, fs, path::Path};
use std::{env, error::Error};
use convert_case::{Case, Casing};
use git2::Repository;
use log::info;
use scripts::{
framework::Framework,
frameworks::{dioxus::Dioxus, leptos::Leptos, yew::Yew},
metadata::Metadata,
};
use tempfile::tempdir;
const GIT_URL: &str = "https://github.com/lucide-icons/lucide.git";
const GIT_REF: &str = "0.507.0";
use scripts::{UPSTREAM_GIT_REF, generate::generate};
fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
let frameworks: [Box<dyn Framework>; 3] = [Box::new(Dioxus), Box::new(Leptos), Box::new(Yew)];
let repository_path = tempdir()?;
let repository_icons_path = repository_path.path().join("icons");
info!(
"Cloning \"{}\" ref \"{}\" into \"{}\".",
GIT_URL,
GIT_REF,
repository_path.path().display()
);
git_checkout(&repository_path)?;
info!("Generating icons.");
let mut paths = vec![];
for entry in fs::read_dir(repository_icons_path)? {
let path = entry?.path();
if !path.is_file() || path.extension().is_none_or(|extension| extension != "svg") {
continue;
}
let file_path = path.clone();
let file_stem = file_path
.file_stem()
.expect("File stem should exist.")
.to_string_lossy()
.to_string();
paths.push((file_path, file_stem));
}
paths.sort_by_key(|(_, file_stem)| file_stem.clone());
let mut modules = vec![];
let mut component_names = vec![];
let mut metadatas = vec![];
for (path, file_stem) in paths {
let file_contents = fs::read_to_string(&path)?;
let mut metadata_path = path.clone();
metadata_path.set_extension("json");
let metadata = serde_json::from_str::<Metadata>(&fs::read_to_string(&metadata_path)?)?;
metadatas.push(metadata.clone());
let module = file_stem.to_case(Case::Snake);
modules.push(module.clone());
let component_name = file_stem.to_case(Case::Pascal);
component_names.push(component_name.clone());
info!("{module} - {component_name}");
for framework in &frameworks {
generate_icon(
&**framework,
module.clone(),
component_name.clone(),
file_contents.clone(),
)?;
}
}
for framework in &frameworks {
generate_lib(&**framework, &modules, &metadatas)?;
generate_example(&**framework, &component_names)?;
generate_features(&**framework, &metadatas)?;
framework.format(
format!("lucide-{}", framework.name()),
Path::new("packages").join(framework.name()).join("src"),
)?;
framework.format(
format!("lucide-{}-book", framework.name()),
Path::new("book-examples")
.join(framework.name())
.join("src"),
)?;
}
Ok(())
}
fn git_checkout<P: AsRef<Path>>(path: P) -> Result<(), Box<dyn Error>> {
let repository = Repository::clone(GIT_URL, path)?;
let (object, reference) = repository.revparse_ext(GIT_REF)?;
repository.checkout_tree(&object, None)?;
match reference {
Some(reference) => {
repository.set_head(reference.name().expect("Reference name should exist."))?
}
None => repository.set_head_detached(object.id())?,
}
Ok(())
}
fn generate_icon(
framework: &dyn Framework,
module: String,
component_name: String,
input: String,
) -> Result<(), Box<dyn Error>> {
let output_path = Path::new("packages")
.join(framework.name())
.join("src")
.join(format!("{module}.rs"));
let output_tokens = framework.generate(component_name, input)?;
let output = prettyplease::unparse(&syn::parse2(output_tokens)?);
fs::write(output_path, output)?;
Ok(())
}
fn generate_example(
framework: &dyn Framework,
component_names: &[String],
) -> Result<(), Box<dyn Error>> {
let output_path = Path::new("book-examples")
.join(framework.name())
.join("src")
.join("icons.rs");
let output_tokens = framework.generate_example(component_names)?;
let output = prettyplease::unparse(&syn::parse2(output_tokens)?);
fs::write(output_path, output)?;
Ok(())
}
fn generate_lib(
framework: &dyn Framework,
modules: &[String],
metadatas: &[Metadata],
) -> Result<(), Box<dyn Error>> {
let attributes = metadatas
.iter()
.map(|metadata| {
let conditions = metadata
.categories
.iter()
.map(|category| format!("feature = \"{category}\""))
.collect::<Vec<_>>();
if conditions.len() == 1 {
format!("#[cfg({})]", conditions.join(", "))
} else {
format!("#[cfg(any({}))]", conditions.join(", "))
}
})
.collect::<Vec<String>>();
let output_path = Path::new("packages")
.join(framework.name())
.join("src")
.join("lib.rs");
let output_modules = modules
.iter()
.zip(&attributes)
.map(|(module, attribute)| {
format!("{attribute}\nmod {};", sanitize_identifier(module.as_str()))
})
.collect::<Vec<String>>()
.join("\n");
let output_uses = modules
.iter()
.zip(&attributes)
.map(|(module, attribute)| {
format!(
"{attribute}\npub use {}::*;",
sanitize_identifier(module.as_str())
)
})
.collect::<Vec<String>>()
.join("\n");
let output = format!(
"{}{}\n\n{}\n",
match framework.lib_header() {
Some(header) => format!("{header}\n\n"),
None => "".into(),
},
output_modules,
output_uses
);
fs::write(output_path, output)?;
Ok(())
}
fn generate_features(
framework: &dyn Framework,
metadatas: &[Metadata],
) -> Result<(), Box<dyn Error>> {
let file_path = Path::new("packages")
.join(framework.name())
.join("Cargo.toml");
let mut file_contents = fs::read_to_string(&file_path)?;
let index = file_contents.find("[features]");
if let Some(index) = index {
file_contents = file_contents[0..index].to_string();
}
file_contents = file_contents.trim_end_matches("\n").to_string();
let mut features = metadatas
.iter()
.flat_map(|metadata| metadata.categories.clone())
.collect::<HashSet<String>>()
.into_iter()
.collect::<Vec<String>>();
features.sort();
let output_all_features = features
.iter()
.map(|feature| format!(" \"{feature}\","))
.collect::<Vec<String>>()
.join("\n");
let output_features = features
.into_iter()
.map(|feature| format!("{feature} = []"))
.collect::<Vec<String>>()
.join("\n");
let output = format!(
"{file_contents}\n\n[features]\ndefault = []\n{output_features}\nall-icons = [\n{output_all_features}\n]\n"
);
fs::write(&file_path, output)?;
Ok(())
}
fn sanitize_identifier(identifier: &str) -> &str {
match identifier {
"box" => "r#box",
"move" => "r#move",
"type" => "r#type",
identifier => identifier,
}
generate(UPSTREAM_GIT_REF, env::current_dir()?.as_path())
}

View file

@ -0,0 +1,81 @@
use std::{env, error::Error};
use log::info;
use scripts::{
GIT_URL, UPSTREAM_GIT_REF, UPSTREAM_GIT_URL, UPSTREAM_GITHUB_URL,
generate::generate,
repository::{
git_checkout, git_commit, git_create_branch, git_has_remote_branch, git_push,
git_version_tags, github_create_pull_request,
},
};
use semver::Version;
use tempfile::tempdir;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
env_logger::init();
octocrab::initialise(
octocrab::OctocrabBuilder::new()
.personal_token(env::var("GITHUB_TOKEN")?)
.build()?,
);
let upstream_repository_path = tempdir()?;
let upstream_repository = git_checkout(
&upstream_repository_path,
UPSTREAM_GIT_URL,
UPSTREAM_GIT_REF,
)?;
let current_version = Version::parse(UPSTREAM_GIT_REF.trim_start_matches("v"))?;
let versions = git_version_tags(&upstream_repository)?;
let index = versions
.iter()
.position(|version| *version == current_version);
let new_versions = match index {
Some(index) => &versions[(index + 1)..],
None => &versions,
};
info!("Current version: {current_version}");
if let Some(new_version) = new_versions.iter().next() {
info!("New version: {new_version}");
let next_version = new_version.to_string();
let branch_name = format!("upstream/v{next_version}");
let repository_temp_dir = tempdir()?;
let repository_path = repository_temp_dir.path();
let repository = git_checkout(repository_path, GIT_URL, "main")?;
if git_has_remote_branch(&repository, &branch_name) {
info!("Branch {branch_name} already exists.");
return Ok(());
}
git_create_branch(&repository, &branch_name)?;
generate(&next_version, repository_path)?;
let message = format!("feat: update to upstream v{new_version}");
git_commit(&repository, &message)?;
git_push(&repository, &branch_name)?;
let body = format!(
"Update to upstream [Lucide v{new_version}]({UPSTREAM_GITHUB_URL}/releases/tag/{new_version})."
);
github_create_pull_request(&branch_name, &message, &body).await?;
} else {
info!("No new version.");
}
Ok(())
}

View file

@ -1,4 +1,7 @@
use std::{error::Error, path::PathBuf};
use std::{
error::Error,
path::{Path, PathBuf},
};
use proc_macro2::TokenStream;
@ -11,5 +14,10 @@ pub trait Framework {
fn generate_example(&self, component_names: &[String]) -> Result<TokenStream, Box<dyn Error>>;
fn format(&self, package: String, path: PathBuf) -> Result<(), Box<dyn Error>>;
fn format(
&self,
package: String,
repository_path: &Path,
path: PathBuf,
) -> Result<(), Box<dyn Error>>;
}

View file

@ -1,4 +1,8 @@
use std::{error::Error, path::PathBuf, process::Command};
use std::{
error::Error,
path::{Path, PathBuf},
process::Command,
};
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
@ -144,7 +148,12 @@ impl Framework for Dioxus {
})
}
fn format(&self, package: String, path: PathBuf) -> Result<(), Box<dyn Error>> {
fn format(
&self,
package: String,
repository_path: &Path,
path: PathBuf,
) -> Result<(), Box<dyn Error>> {
Command::new("dx")
.arg("fmt")
.current_dir(path)
@ -155,6 +164,7 @@ impl Framework for Dioxus {
.arg("fmt")
.arg("-p")
.arg(&package)
.current_dir(repository_path)
.status()?
.exit_ok()?;

View file

@ -1,4 +1,8 @@
use std::{error::Error, path::PathBuf, process::Command};
use std::{
error::Error,
path::{Path, PathBuf},
process::Command,
};
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
@ -130,17 +134,24 @@ impl Framework for Leptos {
})
}
fn format(&self, package: String, path: PathBuf) -> Result<(), Box<dyn Error>> {
fn format(
&self,
package: String,
repository_path: &Path,
path: PathBuf,
) -> Result<(), Box<dyn Error>> {
Command::new("cargo")
.arg("fmt")
.arg("-p")
.arg(&package)
.current_dir(repository_path)
.status()?
.exit_ok()?;
Command::new("leptosfmt")
.arg("--quiet")
.arg(path)
.current_dir(repository_path)
.status()?
.exit_ok()?;

View file

@ -1,4 +1,8 @@
use std::{error::Error, path::PathBuf, process::Command};
use std::{
error::Error,
path::{Path, PathBuf},
process::Command,
};
use convert_case::{Case, Casing};
use proc_macro2::TokenStream;
@ -148,12 +152,18 @@ impl Framework for Yew {
})
}
fn format(&self, package: String, _path: PathBuf) -> Result<(), Box<dyn Error>> {
fn format(
&self,
package: String,
repository_path: &Path,
_path: PathBuf,
) -> Result<(), Box<dyn Error>> {
Command::new("cargo")
.arg("fmt")
.arg("-p")
.arg(&package)
.env("RUSTFMT", "yew-fmt")
.current_dir(repository_path)
.status()?
.exit_ok()?;
@ -161,6 +171,7 @@ impl Framework for Yew {
.arg("fmt")
.arg("-p")
.arg(&package)
.current_dir(repository_path)
.status()?
.exit_ok()?;

284
scripts/src/generate.rs Normal file
View file

@ -0,0 +1,284 @@
use std::{collections::HashSet, error::Error, fs, path::Path};
use convert_case::{Case, Casing};
use log::info;
use regex::Regex;
use tempfile::tempdir;
use crate::{
UPSTREAM_GIT_URL,
framework::Framework,
frameworks::{dioxus::Dioxus, leptos::Leptos, yew::Yew},
metadata::Metadata,
repository::git_checkout,
};
pub fn generate(
upstream_repository_rev: &str,
repository_path: &Path,
) -> Result<(), Box<dyn Error>> {
let frameworks: [Box<dyn Framework>; 3] = [Box::new(Dioxus), Box::new(Leptos), Box::new(Yew)];
let upstream_repository_path = tempdir()?;
let repository_icons_path = upstream_repository_path.path().join("icons");
git_checkout(
&upstream_repository_path,
UPSTREAM_GIT_URL,
upstream_repository_rev,
)?;
info!("Generating icons.");
let mut paths = vec![];
for entry in fs::read_dir(repository_icons_path)? {
let path = entry?.path();
if !path.is_file() || path.extension().is_none_or(|extension| extension != "svg") {
continue;
}
let file_path = path.clone();
let file_stem = file_path
.file_stem()
.expect("File stem should exist.")
.to_string_lossy()
.to_string();
paths.push((file_path, file_stem));
}
paths.sort_by_key(|(_, file_stem)| file_stem.clone());
let mut modules = vec![];
let mut component_names = vec![];
let mut metadatas = vec![];
for (path, file_stem) in paths {
let file_contents = fs::read_to_string(&path)?;
let mut metadata_path = path.clone();
metadata_path.set_extension("json");
let metadata = serde_json::from_str::<Metadata>(&fs::read_to_string(&metadata_path)?)?;
metadatas.push(metadata.clone());
let module = file_stem.to_case(Case::Snake);
modules.push(module.clone());
let component_name = file_stem.to_case(Case::Pascal);
component_names.push(component_name.clone());
info!("{module} - {component_name}");
for framework in &frameworks {
generate_icon(
repository_path,
&**framework,
module.clone(),
component_name.clone(),
file_contents.clone(),
)?;
}
}
for framework in &frameworks {
generate_lib(repository_path, &**framework, &modules, &metadatas)?;
generate_example(repository_path, &**framework, &component_names)?;
generate_features(repository_path, &**framework, &metadatas)?;
framework.format(
format!("lucide-{}", framework.name()),
repository_path,
repository_path
.join("packages")
.join(framework.name())
.join("src"),
)?;
framework.format(
format!("lucide-{}-book", framework.name()),
repository_path,
repository_path
.join("book-examples")
.join(framework.name())
.join("src"),
)?;
}
update_repository_rev(repository_path, upstream_repository_rev)?;
Ok(())
}
fn generate_icon(
path: &Path,
framework: &dyn Framework,
module: String,
component_name: String,
input: String,
) -> Result<(), Box<dyn Error>> {
let output_path = path
.join("packages")
.join(framework.name())
.join("src")
.join(format!("{module}.rs"));
let output_tokens = framework.generate(component_name, input)?;
let output = prettyplease::unparse(&syn::parse2(output_tokens)?);
fs::write(output_path, output)?;
Ok(())
}
fn generate_example(
path: &Path,
framework: &dyn Framework,
component_names: &[String],
) -> Result<(), Box<dyn Error>> {
let output_path = path
.join("book-examples")
.join(framework.name())
.join("src")
.join("icons.rs");
let output_tokens = framework.generate_example(component_names)?;
let output = prettyplease::unparse(&syn::parse2(output_tokens)?);
fs::write(output_path, output)?;
Ok(())
}
fn generate_lib(
path: &Path,
framework: &dyn Framework,
modules: &[String],
metadatas: &[Metadata],
) -> Result<(), Box<dyn Error>> {
let attributes = metadatas
.iter()
.map(|metadata| {
let conditions = metadata
.categories
.iter()
.map(|category| format!("feature = \"{category}\""))
.collect::<Vec<_>>();
if conditions.len() == 1 {
format!("#[cfg({})]", conditions.join(", "))
} else {
format!("#[cfg(any({}))]", conditions.join(", "))
}
})
.collect::<Vec<String>>();
let output_path = path
.join("packages")
.join(framework.name())
.join("src")
.join("lib.rs");
let output_modules = modules
.iter()
.zip(&attributes)
.map(|(module, attribute)| {
format!("{attribute}\nmod {};", sanitize_identifier(module.as_str()))
})
.collect::<Vec<String>>()
.join("\n");
let output_uses = modules
.iter()
.zip(&attributes)
.map(|(module, attribute)| {
format!(
"{attribute}\npub use {}::*;",
sanitize_identifier(module.as_str())
)
})
.collect::<Vec<String>>()
.join("\n");
let output = format!(
"{}{}\n\n{}\n",
match framework.lib_header() {
Some(header) => format!("{header}\n\n"),
None => "".into(),
},
output_modules,
output_uses
);
fs::write(output_path, output)?;
Ok(())
}
fn generate_features(
path: &Path,
framework: &dyn Framework,
metadatas: &[Metadata],
) -> Result<(), Box<dyn Error>> {
let file_path = path
.join("packages")
.join(framework.name())
.join("Cargo.toml");
let mut file_contents = fs::read_to_string(&file_path)?;
let index = file_contents.find("[features]");
if let Some(index) = index {
file_contents = file_contents[0..index].to_string();
}
file_contents = file_contents.trim_end_matches("\n").to_string();
let mut features = metadatas
.iter()
.flat_map(|metadata| metadata.categories.clone())
.collect::<HashSet<String>>()
.into_iter()
.collect::<Vec<String>>();
features.sort();
let output_all_features = features
.iter()
.map(|feature| format!(" \"{feature}\","))
.collect::<Vec<String>>()
.join("\n");
let output_features = features
.into_iter()
.map(|feature| format!("{feature} = []"))
.collect::<Vec<String>>()
.join("\n");
let output = format!(
"{file_contents}\n\n[features]\ndefault = []\n{output_features}\nall-icons = [\n{output_all_features}\n]\n"
);
fs::write(&file_path, output)?;
Ok(())
}
fn update_repository_rev(path: &Path, repository_rev: &str) -> Result<(), Box<dyn Error>> {
let file_path = path.join("scripts").join("src").join("lib.rs");
let file_contents = fs::read_to_string(&file_path)?;
let regex = Regex::new(r"\d+\.\d+\.\d+")?;
let output = regex.replace(&file_contents, repository_rev).to_string();
fs::write(&file_path, output)?;
Ok(())
}
fn sanitize_identifier(identifier: &str) -> &str {
match identifier {
"box" => "r#box",
"move" => "r#move",
"type" => "r#type",
identifier => identifier,
}
}

View file

@ -1,5 +1,15 @@
#![feature(exit_status_error)]
pub mod framework;
pub mod frameworks;
pub mod metadata;
mod framework;
mod frameworks;
pub mod generate;
mod metadata;
pub mod repository;
pub const GIT_URL: &str = "https://github.com/RustForWeb/lucide.git";
pub const GITHUB_OWNER: &str = "RustForWeb";
pub const GITHUB_REPO: &str = "lucide";
pub const UPSTREAM_GIT_URL: &str = "https://github.com/lucide-icons/lucide.git";
pub const UPSTREAM_GIT_REF: &str = "0.507.0";
pub const UPSTREAM_GITHUB_URL: &str = "https://github.com/lucide-icons/lucide";

140
scripts/src/repository.rs Normal file
View file

@ -0,0 +1,140 @@
use std::{env, error::Error, path::Path};
use git2::{BranchType, Cred, IndexAddOption, PushOptions, RemoteCallbacks, Repository, Signature};
use log::info;
use semver::Version;
use crate::{GITHUB_OWNER, GITHUB_REPO, UPSTREAM_GIT_URL};
pub fn git_checkout<P: AsRef<Path>>(
path: P,
url: &str,
r#ref: &str,
) -> Result<Repository, Box<dyn Error>> {
info!(
"Cloning \"{}\" ref \"{}\" into \"{}\".",
UPSTREAM_GIT_URL,
r#ref,
path.as_ref().display()
);
let repository = Repository::clone(url, path)?;
{
let (object, reference) = repository.revparse_ext(r#ref)?;
repository.checkout_tree(&object, None)?;
match reference {
Some(reference) => {
repository.set_head(reference.name().expect("Reference name should exist."))?
}
None => repository.set_head_detached(object.id())?,
}
}
Ok(repository)
}
pub fn git_version_tags(repository: &Repository) -> Result<Vec<Version>, Box<dyn Error>> {
let tag_names = repository.tag_names(None)?;
let mut tag_names = tag_names
.into_iter()
.flat_map(|tag_name| {
tag_name.and_then(|tag_name| Version::parse(tag_name.trim_start_matches("v")).ok())
})
.collect::<Vec<_>>();
tag_names.sort();
Ok(tag_names)
}
pub fn git_has_remote_branch(repository: &Repository, branch_name: &str) -> bool {
repository
.find_branch(branch_name, BranchType::Remote)
.is_ok()
}
pub fn git_create_branch(repository: &Repository, branch_name: &str) -> Result<(), Box<dyn Error>> {
info!("Creating branch {branch_name}.");
let branch = repository.branch(branch_name, &repository.head()?.peel_to_commit()?, false)?;
repository.set_head(
branch
.into_reference()
.name()
.expect("Reference name should exist."),
)?;
Ok(())
}
pub fn git_commit(repository: &Repository, message: &str) -> Result<(), Box<dyn Error>> {
info!("Committing.");
repository
.index()?
.add_all(["."], IndexAddOption::DEFAULT, None)?;
repository.index()?.write()?;
let signature = Signature::now(&env::var("GIT_USER_NAME")?, &env::var("GIT_USER_EMAIL")?)?;
let tree = repository.find_tree(repository.index()?.write_tree()?)?;
let parent = repository.head()?.peel_to_commit()?;
repository.commit(
Some("HEAD"),
&signature,
&signature,
message,
&tree,
&[&parent],
)?;
Ok(())
}
pub fn git_push(repository: &Repository, branch_name: &str) -> Result<(), Box<dyn Error>> {
info!("Pushing branch {branch_name}.");
let branch = repository.find_branch(branch_name, BranchType::Local)?;
let branch_reference = branch.into_reference();
let branch_ref = branch_reference
.name()
.expect("Reference name should exist.");
let username = env::var("GITHUB_ACTOR")?;
let password = env::var("GITHUB_TOKEN")?;
let mut callbacks = RemoteCallbacks::new();
callbacks.credentials(|_, _, _| Cred::userpass_plaintext(&username, &password));
let mut options = PushOptions::new();
options.remote_callbacks(callbacks);
let mut remote = repository.find_remote("origin")?;
remote.push(&[branch_ref], Some(&mut options))?;
Ok(())
}
pub async fn github_create_pull_request(
branch_name: &str,
title: &str,
body: &str,
) -> Result<(), Box<dyn Error>> {
let octocrab = octocrab::instance();
info!("Creating pull request for branch {branch_name}.");
octocrab
.pulls(GITHUB_OWNER, GITHUB_REPO)
.create(title, branch_name, "main")
.body(body)
.draft(true)
.send()
.await?;
Ok(())
}