Compare commits

..

2 Commits

Author SHA1 Message Date
cuddle-please
4988553d9a chore(release): 0.2.0
Some checks failed
continuous-integration/drone/push Build is passing
continuous-integration/drone/pr Build is failing
2024-09-14 13:13:57 +00:00
6a0900e190
feat: add github fetch prs refactoring
All checks were successful
continuous-integration/drone/push Build is passing
Signed-off-by: kjuulh <contact@kjuulh.io>
2024-09-14 15:10:46 +02:00
9 changed files with 722 additions and 56 deletions

View File

@ -6,9 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [0.2.0] - 2024-09-13
## [0.2.0] - 2024-09-14
### Added
- add github fetch prs refactoring
- gitea able to pull repositories
- add config

462
Cargo.lock generated
View File

@ -17,6 +17,21 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
[[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.15"
@ -72,6 +87,12 @@ version = "1.0.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e1496f8fb1fbf272686b8d37f523dab3e4a7443300055e74cdaa449f3114356"
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "async-trait"
version = "0.1.82"
@ -110,6 +131,12 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "base64"
version = "0.22.1"
@ -149,6 +176,19 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "chrono"
version = "0.4.38"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401"
dependencies = [
"android-tzdata",
"iana-time-zone",
"num-traits",
"serde",
"windows-targets",
]
[[package]]
name = "clap"
version = "4.5.17"
@ -211,12 +251,27 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b"
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
]
[[package]]
name = "dotenv"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
[[package]]
name = "encoding_rs"
version = "0.8.34"
@ -278,6 +333,21 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "futures"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
dependencies = [
"futures-channel",
"futures-core",
"futures-executor",
"futures-io",
"futures-sink",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-channel"
version = "0.3.30"
@ -285,6 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
dependencies = [
"futures-core",
"futures-sink",
]
[[package]]
@ -293,6 +364,34 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
[[package]]
name = "futures-executor"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
dependencies = [
"futures-core",
"futures-task",
"futures-util",
]
[[package]]
name = "futures-io"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
[[package]]
name = "futures-macro"
version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "futures-sink"
version = "0.3.30"
@ -311,10 +410,16 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
dependencies = [
"futures-channel",
"futures-core",
"futures-io",
"futures-macro",
"futures-sink",
"futures-task",
"memchr",
"pin-project-lite",
"pin-utils",
"slab",
]
[[package]]
@ -324,8 +429,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi",
"wasm-bindgen",
]
[[package]]
@ -356,6 +463,7 @@ dependencies = [
"clap",
"dotenv",
"gitea-rs",
"octocrab",
"serde",
"tokio",
"toml",
@ -462,6 +570,25 @@ dependencies = [
"want",
]
[[package]]
name = "hyper-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
dependencies = [
"futures-util",
"http",
"hyper",
"hyper-util",
"log",
"rustls 0.22.4",
"rustls-native-certs",
"rustls-pki-types",
"tokio",
"tokio-rustls 0.25.0",
"tower-service",
]
[[package]]
name = "hyper-rustls"
version = "0.27.3"
@ -472,10 +599,23 @@ dependencies = [
"http",
"hyper",
"hyper-util",
"rustls",
"rustls 0.23.13",
"rustls-pki-types",
"tokio",
"tokio-rustls",
"tokio-rustls 0.26.0",
"tower-service",
]
[[package]]
name = "hyper-timeout"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793"
dependencies = [
"hyper",
"hyper-util",
"pin-project-lite",
"tokio",
"tower-service",
]
@ -515,6 +655,29 @@ dependencies = [
"tracing",
]
[[package]]
name = "iana-time-zone"
version = "0.1.60"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"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 = "idna"
version = "0.5.0"
@ -541,6 +704,16 @@ version = "2.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4"
[[package]]
name = "iri-string"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0f755bd3806e06ad4f366f92639415d99a339a2c7ecf8c26ccea2097c11cb6"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
@ -562,6 +735,21 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonwebtoken"
version = "9.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9ae10193d25051e74945f1ea2d0b42e03cc3b890f7e4cc5faa44997d808193f"
dependencies = [
"base64 0.21.7",
"js-sys",
"pem",
"ring",
"serde",
"serde_json",
"simple_asn1",
]
[[package]]
name = "lazy_static"
version = "1.5.0"
@ -666,6 +854,40 @@ dependencies = [
"winapi",
]
[[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"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "object"
version = "0.36.4"
@ -675,6 +897,45 @@ dependencies = [
"memchr",
]
[[package]]
name = "octocrab"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9305e4c99543ecd0f42bd659c9e9d6ca7115fe5e37d5c85a7277b1db0d4c4101"
dependencies = [
"arc-swap",
"async-trait",
"base64 0.22.1",
"bytes",
"cfg-if",
"chrono",
"either",
"futures",
"futures-util",
"http",
"http-body",
"http-body-util",
"hyper",
"hyper-rustls 0.26.0",
"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",
]
[[package]]
name = "once_cell"
version = "1.19.0"
@ -754,6 +1015,16 @@ dependencies = [
"windows-targets",
]
[[package]]
name = "pem"
version = "3.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae"
dependencies = [
"base64 0.22.1",
"serde",
]
[[package]]
name = "percent-encoding"
version = "2.3.1"
@ -798,6 +1069,12 @@ version = "0.3.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "proc-macro2"
version = "1.0.86"
@ -831,7 +1108,7 @@ version = "0.12.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63"
dependencies = [
"base64",
"base64 0.22.1",
"bytes",
"encoding_rs",
"futures-core",
@ -841,7 +1118,7 @@ dependencies = [
"http-body",
"http-body-util",
"hyper",
"hyper-rustls",
"hyper-rustls 0.27.3",
"hyper-tls",
"hyper-util",
"ipnet",
@ -903,6 +1180,20 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rustls"
version = "0.22.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf4ef73721ac7bcd79b2b315da7779d8fc09718c6b3d2d1b2d94850eb8c18432"
dependencies = [
"log",
"ring",
"rustls-pki-types",
"rustls-webpki",
"subtle",
"zeroize",
]
[[package]]
name = "rustls"
version = "0.23.13"
@ -916,13 +1207,26 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rustls-native-certs"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5bfb394eeed242e909609f56089eecfe5fda225042e8b171791b9c95f5931e5"
dependencies = [
"openssl-probe",
"rustls-pemfile",
"rustls-pki-types",
"schannel",
"security-framework",
]
[[package]]
name = "rustls-pemfile"
version = "2.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425"
dependencies = [
"base64",
"base64 0.22.1",
"rustls-pki-types",
]
@ -964,6 +1268,15 @@ version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
[[package]]
name = "secrecy"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9bd1c54ea06cfd2f6b63219704de0b9b4f72dcc2b8fdef820be6cd799780e91e"
dependencies = [
"zeroize",
]
[[package]]
name = "security-framework"
version = "2.11.1"
@ -1019,6 +1332,16 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_path_to_error"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "af99884400da37c88f5e9146b7f1fd0fbcae8f6eec4e9da38b67d05486f814a6"
dependencies = [
"itoa",
"serde",
]
[[package]]
name = "serde_repr"
version = "0.1.19"
@ -1075,6 +1398,18 @@ dependencies = [
"libc",
]
[[package]]
name = "simple_asn1"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085"
dependencies = [
"num-bigint",
"num-traits",
"thiserror",
"time",
]
[[package]]
name = "slab"
version = "0.4.9"
@ -1090,6 +1425,27 @@ version = "1.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
[[package]]
name = "snafu"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b835cb902660db3415a672d862905e791e54d306c6e8189168c7f3d9ae1c79d"
dependencies = [
"snafu-derive",
]
[[package]]
name = "snafu-derive"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38d1e02fca405f6280643174a50c942219f0bbf4dbf7d480f1dd864d6f211ae5"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "socket2"
version = "0.5.7"
@ -1172,6 +1528,26 @@ dependencies = [
"windows-sys 0.59.0",
]
[[package]]
name = "thiserror"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.63"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "thread_local"
version = "1.1.8"
@ -1182,6 +1558,37 @@ dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.3.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tinyvec"
version = "1.8.0"
@ -1236,13 +1643,24 @@ dependencies = [
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
dependencies = [
"rustls 0.22.4",
"rustls-pki-types",
"tokio",
]
[[package]]
name = "tokio-rustls"
version = "0.26.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
dependencies = [
"rustls",
"rustls 0.23.13",
"rustls-pki-types",
"tokio",
]
@ -1305,8 +1723,30 @@ dependencies = [
"pin-project",
"pin-project-lite",
"tokio",
"tokio-util",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
name = "tower-http"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5"
dependencies = [
"bitflags",
"bytes",
"futures-util",
"http",
"http-body",
"http-body-util",
"iri-string",
"pin-project-lite",
"tower",
"tower-layer",
"tower-service",
"tracing",
]
[[package]]
@ -1430,6 +1870,7 @@ dependencies = [
"form_urlencoded",
"idna",
"percent-encoding",
"serde",
]
[[package]]
@ -1580,6 +2021,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
[[package]]
name = "windows-core"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-registry"
version = "0.2.0"

View File

@ -19,3 +19,4 @@ toml = "0.8.19"
gitea-rs = { git = "https://git.front.kjuulh.io/kjuulh/gitea-rs", version = "1.22.1" }
url = "2.5.2"
octocrab = "0.39.0"

View File

@ -1,10 +1,4 @@
use crate::{
app::App,
git_provider::{
gitea::GiteaProviderApp, github::GitHubProviderApp, GitProvider, VecRepositoryExt,
},
projects_list::ProjectsListApp,
};
use crate::{ app::App, projects_list::ProjectsListApp};
#[derive(Debug, Clone)]
pub struct RootCommand {

View File

@ -19,6 +19,14 @@ pub struct Providers {
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct GitHub {
#[serde(default)]
pub url: Option<String>,
pub access_token: GitHubAccessToken,
#[serde(default)]
pub current_user: Option<String>,
#[serde(default)]
pub users: Vec<GitHubUser>,
#[serde(default)]
@ -28,12 +36,38 @@ pub struct GitHub {
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct GitHubUser(String);
impl From<GitHubUser> for String {
fn from(value: GitHubUser) -> Self {
value.0
}
}
impl<'a> From<&'a GitHubUser> for &'a str {
fn from(value: &'a GitHubUser) -> Self {
value.0.as_str()
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct GitHubOrganisation(String);
impl From<GitHubOrganisation> for String {
fn from(value: GitHubOrganisation) -> Self {
value.0
}
}
impl<'a> From<&'a GitHubOrganisation> for &'a str {
fn from(value: &'a GitHubOrganisation) -> Self {
value.0.as_str()
}
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Gitea {
pub url: String,
#[serde(default)]
pub access_token: Option<GiteaAccessToken>,
#[serde(default)]
@ -52,6 +86,13 @@ pub enum GiteaAccessToken {
Env { env: String },
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(untagged)]
pub enum GitHubAccessToken {
Direct(String),
Env { env: String },
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct GiteaUser(String);
@ -138,11 +179,19 @@ mod test {
github: vec![
GitHub {
users: vec![GitHubUser("kjuulh".into())],
organisations: vec![GitHubOrganisation("lunarway".into())]
organisations: vec![GitHubOrganisation("lunarway".into())],
url: None,
access_token: GitHubAccessToken::Direct("some-token".into()),
current_user: Some("kjuulh".into())
},
GitHub {
users: vec![GitHubUser("other".into())],
organisations: vec![GitHubOrganisation("org".into())]
organisations: vec![GitHubOrganisation("org".into())],
url: None,
access_token: GitHubAccessToken::Env {
env: "something".into()
},
current_user: None
}
],
gitea: vec![

View File

@ -1,6 +1,4 @@
use std::{collections::HashMap, path::PathBuf, str::FromStr};
use async_trait::async_trait;
use std::path::PathBuf;
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct Repository {
@ -31,14 +29,5 @@ impl VecRepositoryExt for Vec<Repository> {
}
}
#[async_trait]
pub trait GitProvider {
async fn list_repositories_for_user(&self, user: &str) -> anyhow::Result<Vec<Repository>>;
async fn list_repositories_for_organisation(
&self,
organisation: &str,
) -> anyhow::Result<Vec<Repository>>;
}
pub mod gitea;
pub mod github;

View File

@ -1,11 +1,12 @@
use anyhow::Context;
use gitea_rs::apis::configuration::{ApiKey, Configuration};
use gitea_rs::apis::configuration::Configuration;
use url::Url;
use crate::{app::App, config::GiteaAccessToken};
#[derive(Debug)]
pub struct GiteaProvider {
#[allow(dead_code)]
app: &'static App,
}
@ -14,14 +15,12 @@ impl GiteaProvider {
GiteaProvider { app }
}
#[tracing::instrument(skip(self))]
pub async fn list_repositories_for_current_user(
&self,
user: &str,
api: &str,
access_token: Option<&GiteaAccessToken>,
) -> anyhow::Result<Vec<super::Repository>> {
tracing::debug!("fetching gitea repositories for user");
tracing::debug!("fetching gitea repositories for current user");
let config = self.get_config(api, access_token)?;
@ -29,7 +28,7 @@ impl GiteaProvider {
let mut page = 1;
loop {
let mut repos = self
.list_repositories_for_current_user_with_page(user, &config, page)
.list_repositories_for_current_user_with_page(&config, page)
.await?;
if repos.is_empty() {
@ -65,10 +64,8 @@ impl GiteaProvider {
Ok(provider.into())
}
#[tracing::instrument(skip(self))]
async fn list_repositories_for_current_user_with_page(
&self,
user: &str,
config: &Configuration,
page: usize,
) -> anyhow::Result<Vec<gitea_rs::models::Repository>> {
@ -80,14 +77,13 @@ impl GiteaProvider {
Ok(repos)
}
#[tracing::instrument(skip(self))]
pub async fn list_repositories_for_user(
&self,
user: &str,
api: &str,
access_token: Option<&GiteaAccessToken>,
) -> anyhow::Result<Vec<super::Repository>> {
tracing::debug!("fetching gitea repositories for user");
tracing::debug!(user = user, "fetching gitea repositories for user");
let config = self.get_config(api, access_token)?;
@ -146,6 +142,10 @@ impl GiteaProvider {
api: &str,
access_token: Option<&GiteaAccessToken>,
) -> anyhow::Result<Vec<super::Repository>> {
tracing::debug!(
organisation = organisation,
"fetching gitea repositories for organisation"
);
let config = self.get_config(api, access_token)?;
let mut repositories = Vec::new();

View File

@ -1,10 +1,15 @@
use async_trait::async_trait;
use anyhow::Context;
use octocrab::{
auth::Auth,
models::{hooks::Config, Repository},
params::repos::Sort,
NoSvc, Octocrab, Page,
};
use crate::app::App;
use super::GitProvider;
use crate::{app::App, config::GitHubAccessToken};
pub struct GitHubProvider {
#[allow(dead_code)]
app: &'static App,
}
@ -12,22 +17,159 @@ impl GitHubProvider {
pub fn new(app: &'static App) -> GitHubProvider {
GitHubProvider { app }
}
pub async fn list_repositories_for_current_user(
&self,
url: Option<&String>,
access_token: &GitHubAccessToken,
) -> anyhow::Result<Vec<super::Repository>> {
tracing::debug!("fetching github repositories for current user");
let client = self.get_client(url, access_token)?;
let current_page = client
.current()
.list_repos_for_authenticated_user()
.type_("all")
.per_page(100)
.sort("full_name")
.send()
.await?;
let repos = self.unfold_pages(client, current_page).await?;
Ok(repos
.into_iter()
.filter_map(|repo| {
Some(super::Repository {
provider: self.get_url(url),
owner: repo.owner.map(|su| su.login)?,
repo_name: repo.name,
ssh_url: repo.ssh_url?,
})
})
.collect())
}
#[async_trait]
impl GitProvider for GitHubProvider {
async fn list_repositories_for_user(
pub async fn list_repositories_for_user(
&self,
user: &str,
url: Option<&String>,
access_token: &GitHubAccessToken,
) -> anyhow::Result<Vec<super::Repository>> {
todo!()
tracing::debug!(user = user, "fetching github repositories for user");
let client = self.get_client(url, access_token)?;
let current_page = client
.users(user)
.repos()
.r#type(octocrab::params::users::repos::Type::All)
.sort(Sort::FullName)
.per_page(100)
.send()
.await?;
let repos = self.unfold_pages(client, current_page).await?;
Ok(repos
.into_iter()
.filter_map(|repo| {
Some(super::Repository {
provider: self.get_url(url),
owner: repo.owner.map(|su| su.login)?,
repo_name: repo.name,
ssh_url: repo.ssh_url?,
})
})
.collect())
}
async fn list_repositories_for_organisation(
pub async fn list_repositories_for_organisation(
&self,
organisation: &str,
url: Option<&String>,
access_token: &GitHubAccessToken,
) -> anyhow::Result<Vec<super::Repository>> {
todo!()
tracing::debug!(
organisation = organisation,
"fetching github repositories for organisation"
);
let client = self.get_client(url, access_token)?;
let current_page = client
.orgs(organisation)
.list_repos()
.repo_type(Some(octocrab::params::repos::Type::All))
.sort(Sort::FullName)
.per_page(100)
.send()
.await?;
let repos = self.unfold_pages(client, current_page).await?;
Ok(repos
.into_iter()
.filter_map(|repo| {
Some(super::Repository {
provider: self.get_url(url),
owner: repo.owner.map(|su| su.login)?,
repo_name: repo.name,
ssh_url: repo.ssh_url?,
})
})
.collect())
}
async fn unfold_pages(
&self,
client: octocrab::Octocrab,
page: Page<Repository>,
) -> anyhow::Result<Vec<Repository>> {
let mut current_page = page;
let mut repos = current_page.take_items();
while let Ok(Some(mut new_page)) = client.get_page(&current_page.next).await {
repos.extend(new_page.take_items());
current_page = new_page;
}
Ok(repos)
}
fn get_url(&self, url: Option<&String>) -> String {
let default_domain = "github.com".to_string();
if let Some(url) = url {
let Some(url) = url::Url::parse(url).ok() else {
return default_domain;
};
let Some(domain) = url.domain().map(|d| d.to_string()) else {
return default_domain;
};
domain
} else {
default_domain
}
}
fn get_client(
&self,
url: Option<&String>,
access_token: &GitHubAccessToken,
) -> anyhow::Result<Octocrab> {
let client = octocrab::Octocrab::builder()
.personal_token(match access_token {
GitHubAccessToken::Direct(token) => token.to_owned(),
GitHubAccessToken::Env { env } => std::env::var(env)?,
})
.build()?;
Ok(client)
}
}

View File

@ -1,6 +1,8 @@
use crate::{
app::App,
git_provider::{gitea::GiteaProviderApp, Repository, VecRepositoryExt},
git_provider::{
gitea::GiteaProviderApp, github::GitHubProviderApp, Repository, VecRepositoryExt,
},
};
pub struct ProjectsList {
@ -16,6 +18,7 @@ impl ProjectsList {
let mut repositories = Vec::new();
repositories.extend(self.get_gitea_projects().await?);
repositories.extend(self.get_github_projects().await?);
repositories.collect_unique();
@ -27,13 +30,9 @@ impl ProjectsList {
let mut repositories = Vec::new();
for gitea in self.app.config.providers.gitea.iter() {
if let Some(user) = &gitea.current_user {
if let Some(_user) = &gitea.current_user {
let mut repos = gitea_provider
.list_repositories_for_current_user(
user,
&gitea.url,
gitea.access_token.as_ref(),
)
.list_repositories_for_current_user(&gitea.url, gitea.access_token.as_ref())
.await?;
repositories.append(&mut repos);
@ -66,6 +65,47 @@ impl ProjectsList {
Ok(repositories)
}
async fn get_github_projects(&self) -> anyhow::Result<Vec<Repository>> {
let github_provider = self.app.github_provider();
let mut repositories = Vec::new();
for github in self.app.config.providers.github.iter() {
if let Some(_user) = &github.current_user {
let mut repos = github_provider
.list_repositories_for_current_user(github.url.as_ref(), &github.access_token)
.await?;
repositories.append(&mut repos);
}
for github_user in github.users.iter() {
let mut repos = github_provider
.list_repositories_for_user(
github_user.into(),
github.url.as_ref(),
&github.access_token,
)
.await?;
repositories.append(&mut repos);
}
for github_org in github.organisations.iter() {
let mut repos = github_provider
.list_repositories_for_organisation(
github_org.into(),
github.url.as_ref(),
&github.access_token,
)
.await?;
repositories.append(&mut repos);
}
}
Ok(repositories)
}
}
pub trait ProjectsListApp {