Skip to content

ci changes #289

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 5 additions & 51 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [windows-latest, ubuntu-latest]
os: [ubuntu-latest]
rust: [1.64.0, nightly]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -47,11 +47,9 @@ jobs:
toolchain: ${{ matrix.rust }}
override: true
- uses: Swatinem/rust-cache@v2
- uses: taiki-e/install-action@nextest
- name: Test twitch_api
uses: actions-rs/cargo@v1
with:
command: test
args: --locked --all-targets --features "${{ env.CI_TWITCH_API_FEATURES }}" --workspace
run: cargo xtask test
fmt:
name: Rustfmt
runs-on: ubuntu-latest
Expand Down Expand Up @@ -84,46 +82,8 @@ jobs:
override: true
components: clippy
- uses: Swatinem/rust-cache@v2
- name: Run clippy --all-targets --no-default-features
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --no-default-features -p twitch_api
- name: Run clippy --all-targets --no-default-features --features "helix"
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --no-default-features --features "helix" -p twitch_api
- name: Run clippy --all-targets --no-default-features --features "helix client"
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --no-default-features --features "helix client" -p twitch_api
- name: Run clippy --all-targets --no-default-features --features "tmi"
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --no-default-features --features "tmi" -p twitch_api
- name: Run clippy --all-targets --no-default-features --features "pubsub"
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --no-default-features --features "pubsub" -p twitch_api
- name: Run clippy --all-targets --features "${{ env.CI_TWITCH_API_FEATURES }} trace_unknown_fields"
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --features "${{ env.CI_TWITCH_API_FEATURES }} trace_unknown_fields" -p twitch_api
- name: Run clippy --all-targets --features "${{ env.CI_TWITCH_API_FEATURES }}"
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --features "${{ env.CI_TWITCH_API_FEATURES }} _all" -p twitch_api
- name: Run clippy --all-targets --all-features --workspace
uses: actions-rs/cargo@v1
with:
command: clippy
args: --locked --all-targets --all-features --workspace
- name: Clippy
run: cargo xtask check --locked -- --deny warnings
docs:
name: Docs
runs-on: ubuntu-latest
Expand All @@ -136,11 +96,5 @@ jobs:
toolchain: nightly
override: true
- uses: Swatinem/rust-cache@v2
# We do the following to make sure docs.rs can document properly without anything broken, and that docs are working.
- name: Run doc tests
uses: actions-rs/cargo@v1
with:
command: test
args: --doc --features "${{ env.CI_TWITCH_API_FEATURES }} _all"
- name: Check twitch_api docs
run: cargo xtask doc
16 changes: 16 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions src/helix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ use serde::Deserialize;
#[doc(no_inline)]
#[cfg(feature = "twitch_oauth2")]
pub use twitch_oauth2::Scope;
#[cfg(feature = "twitch_oauth2")]
#[cfg(feature = "client")]
use twitch_oauth2::TwitchToken;

#[cfg(feature = "client")]
Expand Down Expand Up @@ -75,7 +75,7 @@ struct InnerResponse<D> {
}

#[derive(Deserialize, Debug)]
#[cfg(feature = "unsupported")]
#[cfg(all(feature = "unsupported", feature = "client"))]
#[cfg_attr(nightly, doc(cfg(feature = "unsupported")))]
struct CustomInnerResponse<'a> {
#[serde(borrow)]
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -217,9 +217,10 @@ impl<'a, C: HttpClient<'a>> TwitchClient<'a, C> {
#[cfg(any(feature = "helix", feature = "tmi"))]
pub fn with_client(client: C) -> TwitchClient<'a, C>
where C: Clone {
// FIXME: This Clone is not used when only using one of the endpoints
TwitchClient {
#[cfg(feature = "tmi")]
#[cfg(all(feature = "tmi", not(feature = "helix")))]
tmi: TmiClient::with_client(client),
#[cfg(all(feature = "tmi", feature = "helix"))]
tmi: TmiClient::with_client(client.clone()),
#[cfg(feature = "helix")]
helix: HelixClient::with_client(client),
Expand Down
3 changes: 3 additions & 0 deletions src/pubsub/channel_subscriptions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ mod tests {
use super::*;

#[test]
#[cfg(feature = "time")]
fn subscription_doc_example_resub() {
// twitch docs broken as usual. /emotes/id is a string and /months is missing
let message = r##"
Expand Down Expand Up @@ -329,6 +330,7 @@ mod tests {
}

#[test]
#[cfg(feature = "time")]
fn subscription_doc_example_subgift() {
let message = r##"
{
Expand Down Expand Up @@ -367,6 +369,7 @@ mod tests {
}

#[test]
#[cfg(feature = "time")]
fn new_sub() {
let message = r##"
{
Expand Down
1 change: 1 addition & 0 deletions xtask/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,4 @@ xshell = "0.2.2"
once_cell = "1.15"
serde_json = "1.0"
serde = { version = "1.0", features = ["derive"] }
itertools = "0.10.5"
42 changes: 42 additions & 0 deletions xtask/src/check.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use itertools::Itertools;
use xshell::{cmd, Shell};

#[derive(Debug, clap::Args)]
pub struct Check {
#[clap(long)]
list: bool,
#[clap(long)]
locked: bool,
#[clap(last = true)]
rest: Vec<String>,
}

impl Check {
pub fn run(&self, sh: &Shell) -> Result<(), color_eyre::Report> {
let Check { rest, locked, list } = self;
let set = crate::features();
if *list {
println!("{}", set.iter().map(|v| v.join(", ")).join("\n"));
return Ok(());
}
println!("Doing {} checks", set.len());
let locked = if *locked { Some("--locked") } else { None };
for features in set {
let features = if !features.is_empty() {
Some(format!("--no-default-features --features={}", features.iter().join(",")))
} else {
None
};
let _section = crate::section(format!(
"Features: {}",
features.as_deref().unwrap_or_default()
));
cmd!(
sh,
"cargo clippy {locked...} --all-targets {features...} -- {rest...}"
)
.run()?;
}
Ok(())
}
}
91 changes: 90 additions & 1 deletion xtask/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,36 @@
pub mod check;
pub mod test;

use std::path::{Path, PathBuf};

use clap::Parser;
use color_eyre::Help;
use itertools::Itertools;
use once_cell::sync::OnceCell;
use serde::Deserialize;
use xshell::{cmd, Shell};

static RUSTDOCFLAGS: &[&str] = &["--cfg", "nightly"];
static RUSTFLAGS: &[&str] = &["--cfg", "nightly"];
static TWITCH_API_FEATURES: &str =
static TWITCH_API_DOC_FEATURES: &str =
"twitch_oauth2/all twitch_oauth2/mock_api all unsupported deny_unknown_fields _all";
static FEATURE_SETS: &[&[&str]] = &[
&["helix"],
&["tmi"],
&["helix", "pubsub", "eventsub", "hmac"],
];
static OPT_FEATURES: &[&[&str]] = &[
&["unsupported"],
&["twitch_oauth2"],
&["client", "deny_unknown_fields"],
&["client", "deny_unknown_fields", "unsupported"],
];
static EXTRA_FEATURES: &[&[&str]] = &[
&["pubsub", "twitch_types/time", "deny_unknown_fields"],
&["trace_unknown_fields", "deny_unknown_fields", "helix"],
&["helix", "tmi"],
&["helix", "eventsub"],
];

#[derive(Debug, Parser)]
pub enum Args {
Expand All @@ -22,6 +43,8 @@ pub enum Args {
#[clap(last = true)]
last: Option<String>,
},
Check(check::Check),
Test(test::Test),
}

fn main() -> color_eyre::Result<()> {
Expand Down Expand Up @@ -125,6 +148,8 @@ fn main() -> color_eyre::Result<()> {
.run()?;
}
}
Args::Check(check) => check.run(&sh)?,
Args::Test(test) => test.run(&sh)?,
}
Ok(())
}
Expand Down Expand Up @@ -197,6 +222,70 @@ pub fn get_cargo_workspace() -> &'static Path {
})
}

fn features() -> Vec<Vec<&'static str>> {
let mut set: Vec<Vec<_>> = vec![all_features()];
for feats in FEATURE_SETS.iter() {
set.push(feats.iter().copied().sorted().collect());
for opt in OPT_FEATURES.iter() {
set.push(
feats
.iter()
.copied()
.chain(opt.iter().copied())
.sorted()
.collect(),
);
}
}
// extras
for extra in EXTRA_FEATURES {
set.push(extra.to_vec())
}
set.sort_by_key(|f| -(f.len() as i32));
set.insert(0, vec![]);
set.into_iter().unique().collect()
}

fn all_features() -> Vec<&'static str> {
crate::FEATURE_SETS
.iter()
.copied()
.flatten()
.chain(crate::OPT_FEATURES.iter().copied().flatten())
.unique()
.copied()
.collect()
}

fn section(name: impl Into<String>) -> impl Drop {
use std::time::Instant;
let ci = std::env::var("CI").is_ok();
let name = name.into();
if ci {
println!("::group::{name}");
}
let start = Instant::now();
defer(move || {
let elapsed = start.elapsed();
eprintln!("{name}: {elapsed:.2?}");
if ci {
println!("::endgroup::");
}
})
}

fn defer<F: FnOnce()>(f: F) -> impl Drop {
struct D<F: FnOnce()>(Option<F>);
impl<F: FnOnce()> Drop for D<F> {
fn drop(&mut self) {
if let Some(f) = self.0.take() {
f()
}
}
}
D(Some(f))
}

#[cfg(test)]
mod tests {
use super::*;
Expand Down
31 changes: 31 additions & 0 deletions xtask/src/test.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
use itertools::Itertools;
use xshell::{cmd, Shell};

#[derive(Debug, clap::Args)]
pub struct Test {
#[clap(long)]
no_nextest: bool,
#[clap(last = true)]
rest: Vec<String>,
}

impl Test {
pub fn run(&self, sh: &Shell) -> Result<(), color_eyre::Report> {
let Test { rest, no_nextest } = self;
let test: &[_] = if *no_nextest {
&["test"]
} else {
&["nextest", "run"]
};

let set = crate::features();
println!("Doing {} test runs", set.len());
for features in set {
let features = features.join(",");
let _section = crate::section(format!("Features: {features}"));
cmd!(sh, "cargo {test...} --features {features} -- {rest...}").run()?;
}

Ok(())
}
}