# use minimum supported rust version for most steps
- name: prepare repo
- image: clux/muslrust:1.64.0
+ image: alpine:3
commands:
+ - apk add git
- git fetch --tags
- git submodule init
- git submodule update --recursive --remote
- - chown 1000:1000 . -R
- - name: check formatting
- image: rustdocker/rust:nightly
+ - name: cargo fmt
+ image: clux/muslrust:1.67.0
+ environment:
+ # store cargo data in repo folder so that it gets cached between steps
+ CARGO_HOME: .cargo
commands:
- - /root/.cargo/bin/cargo fmt -- --check
+ # need make existing toolchain available
+ - cp ~/.cargo . -r
+ - rustup toolchain install nightly
+ - rustup component add rustfmt --toolchain nightly
+ - cargo +nightly fmt -- --check
+
- # latest rust for clippy to get extra checks
- # when adding new clippy lints, make sure to also add them in scripts/fix-clippy.sh
- name: cargo clippy
- image: rust:1.65-buster
+ image: clux/muslrust:1.67.0
environment:
CARGO_HOME: .cargo
commands:
- - apt-get update
- - apt-get install -y --no-install-recommends protobuf-compiler libprotobuf-dev
+ # latest rust for clippy to get extra checks
+ # when adding new clippy lints, make sure to also add them in scripts/fix-clippy.sh
- rustup component add clippy
- cargo clippy --workspace --tests --all-targets --all-features --
-D warnings -D deprecated -D clippy::perf -D clippy::complexity
-D clippy::wildcard_imports -D clippy::cast_lossless
-D clippy::manual_string_new -D clippy::redundant_closure_for_method_calls
-D clippy::unused_self
+ -A clippy::uninlined_format_args
- cargo clippy --workspace --all-features -- -D clippy::unwrap_used
- - name: cargo test
- image: clux/muslrust:1.64.0
+ - name: cargo check
+ image: clux/muslrust:1.67.0
+ environment:
+ CARGO_HOME: .cargo
+ commands:
+ - cargo check --package lemmy_utils
+ - cargo check --package lemmy_db_schema
+ - cargo check --package lemmy_db_views
+ - cargo check --package lemmy_db_views_actor
+ - cargo check --package lemmy_db_views_moderator
+ - cargo check --package lemmy_api_common
+ - cargo check --package lemmy_api
+ - cargo check --package lemmy_api_crud
+ - cargo check --package lemmy_apub
+ - cargo check --package lemmy_routes
+ - cargo check --workspace --no-default-features
+ - cargo check --workspace --all-features
+
+ - name: lemmy_api_common doesnt depend on diesel
+ image: clux/muslrust:1.67.0
environment:
- LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
- LEMMY_CONFIG_LOCATION: ../../config/config.hjson
- RUST_BACKTRACE: 1
- RUST_TEST_THREADS: 1
CARGO_HOME: .cargo
commands:
- - apt-get update
- - apt-get -y install --no-install-recommends postgresql-client protobuf-compiler libprotobuf-dev
- - cargo test --workspace --no-fail-fast --all-features
+ - "! cargo tree -p lemmy_api_common --no-default-features -i diesel"
- name: check defaults.hjson updated
- image: clux/muslrust:1.64.0
+ image: clux/muslrust:1.67.0
environment:
CARGO_HOME: .cargo
commands:
+ - export LEMMY_CONFIG_LOCATION=./config/config.hjson
- ./scripts/update_config_defaults.sh config/defaults_current.hjson
- diff config/defaults.hjson config/defaults_current.hjson
- - name: check with different features
- image: clux/muslrust:1.64.0
+ - name: cargo test
+ image: clux/muslrust:1.67.0
environment:
+ LEMMY_DATABASE_URL: postgres://lemmy:password@database:5432/lemmy
+ RUST_BACKTRACE: 1
+ RUST_TEST_THREADS: 1
CARGO_HOME: .cargo
commands:
- - cargo install cargo-workspaces
- - cargo workspaces exec cargo check --no-default-features
- - cargo workspaces exec cargo check --all-features
-
- - name: lemmy_api_common doesnt depend on diesel
- image: rust:1.64-buster
- commands:
- - "! cargo tree -p lemmy_api_common --no-default-features -i diesel"
+ - export LEMMY_CONFIG_LOCATION=../../config/config.hjson
+ - cargo test --workspace --no-fail-fast
- name: cargo build
- image: clux/muslrust:1.64.0
+ image: clux/muslrust:1.67.0
environment:
CARGO_HOME: .cargo
commands:
password:
from_secret: docker_password
repo: dessalines/lemmy
+ add_host: github.com:140.82.112.3,static.crates.io:18.154.227.73,crates.io:108.138.64.68,dl-cdn.alpinelinux.org:146.75.30.133
tags:
- dev
when:
password:
from_secret: docker_password
repo: dessalines/lemmy
+ add_host: github.com:140.82.112.3,static.crates.io:18.154.227.73,crates.io:108.138.64.68,dl-cdn.alpinelinux.org:146.75.30.133
auto_tag: true
auto_tag_suffix: linux-amd64
when:
# using https://github.com/pksunkara/cargo-workspaces
- name: publish to crates.io
- image: rustlang/rust:nightly
+ image: clux/muslrust:1.67.0
environment:
CARGO_TOKEN:
from_secret: cargo_api_token
ref:
- refs/tags/*
+ - name: Notify on failure
+ image: alpine:3
+ commands:
+ - apk add curl
+ - "curl -d'Drone build failed: ${DRONE_BUILD_LINK}' ntfy.sh/lemmy_drone_ci"
+ when:
+ status:
+ - failure
+
services:
- name: database
- image: postgres:14-alpine
+ image: postgres:15-alpine
environment:
POSTGRES_USER: lemmy
POSTGRES_PASSWORD: password
image: rust:1.57-slim
user: root
commands:
- - chown 1000:1000 . -R
- apt update
- apt install --no-install-recommends --yes git
- git fetch --tags
EndpointType::PrivateMessage => "private_message",
};
- Ok(Url::parse(&format!("{}/{}/{}", domain, point, name))?.into())
+ Ok(Url::parse(&format!("{domain}/{point}/{name}"))?.into())
}
pub fn generate_followers_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
- Ok(Url::parse(&format!("{}/followers", actor_id))?.into())
+ Ok(Url::parse(&format!("{actor_id}/followers"))?.into())
}
pub fn generate_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
- Ok(Url::parse(&format!("{}/inbox", actor_id))?.into())
+ Ok(Url::parse(&format!("{actor_id}/inbox"))?.into())
}
pub fn generate_site_inbox_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
&actor_id.scheme(),
&actor_id.host_str().context(location_info!())?,
if let Some(port) = actor_id.port() {
- format!(":{}", port)
+ format!(":{port}")
} else {
String::new()
},
}
pub fn generate_outbox_url(actor_id: &DbUrl) -> Result<DbUrl, ParseError> {
- Ok(Url::parse(&format!("{}/outbox", actor_id))?.into())
+ Ok(Url::parse(&format!("{actor_id}/outbox"))?.into())
}
pub fn generate_moderators_url(community_id: &DbUrl) -> Result<DbUrl, LemmyError> {
- Ok(Url::parse(&format!("{}/moderators", community_id))?.into())
+ Ok(Url::parse(&format!("{community_id}/moderators"))?.into())
}
.splitn(2, '@')
.collect_tuple()
.ok_or_else(|| LemmyError::from_message("Invalid webfinger query, missing domain"))?;
- let fetch_url = format!(
- "{}://{}/.well-known/webfinger?resource=acct:{}",
- protocol, domain, identifier
- );
+ let fetch_url = format!("{protocol}://{domain}/.well-known/webfinger?resource=acct:{identifier}");
debug!("Fetching webfinger url: {}", &fetch_url);
*request_counter += 1;
from (
select c.id, c.path, count(c2.id) as child_count from comment c
join comment c2 on c2.path <@ c.path and c2.path != c.path
- and c.path <@ '{}'
+ and c.path <@ '{top_parent}'
group by c.id
) as c
-where ca.comment_id = c.id",
- top_parent
+where ca.comment_id = c.id"
);
sql_query(update_child_count_stmt).execute(conn).await?;
let conn = &mut get_conn(pool).await?;
community
.filter(lower(name).eq(lower(community_name)))
- .filter(actor_id.like(format!("{}%", protocol_domain)))
+ .filter(actor_id.like(format!("{protocol_domain}%")))
.first::<Self>(conn)
.await
}
fn bytes_to_hex(bytes: Vec<u8>) -> String {
let mut str = String::new();
for byte in bytes {
- str = format!("{}{:02x}", str, byte);
+ str = format!("{str}{byte:02x}");
}
str
}
let conn = &mut get_conn(pool).await?;
person
.filter(lower(name).eq(lower(person_name)))
- .filter(actor_id.like(format!("{}%", protocol_domain)))
+ .filter(actor_id.like(format!("{protocol_domain}%")))
.first::<Self>(conn)
.await
}
pub fn fuzzy_search(q: &str) -> String {
let replaced = q.replace('%', "\\%").replace('_', "\\_").replace(' ', "%");
- format!("%{}%", replaced)
+ format!("%{replaced}%")
}
pub fn limit_and_offset(
Some(limit) => {
if !(1..=FETCH_LIMIT_MAX).contains(&limit) {
return Err(QueryBuilderError(
- format!("Fetch limit is > {}", FETCH_LIMIT_MAX).into(),
+ format!("Fetch limit is > {FETCH_LIMIT_MAX}").into(),
));
} else {
limit
pub fn run_migrations(db_url: &str) {
// Needs to be a sync connection
let mut conn =
- PgConnection::establish(db_url).unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
+ PgConnection::establish(db_url).unwrap_or_else(|_| panic!("Error connecting to {db_url}"));
info!("Running Database migrations (This may take a long time)...");
let _ = &mut conn
.run_pending_migrations(MIGRATIONS)
Ok(url) => url,
Err(e) => match settings {
Some(settings) => settings.get_database_url(),
- None => panic!(
- "Failed to read database URL from env var LEMMY_DATABASE_URL: {}",
- e
- ),
+ None => panic!("Failed to read database URL from env var LEMMY_DATABASE_URL: {e}"),
},
}
}
channel_builder
.namespaces(RSS_NAMESPACE.clone())
.title(&format!("{} - Inbox", site_view.site.name))
- .link(format!("{}/inbox", protocol_and_hostname,))
+ .link(format!("{protocol_and_hostname}/inbox",))
.items(items);
if let Some(site_desc) = site_view.site.description {
protocol_and_hostname: &str,
) -> Result<Item, LemmyError> {
let mut i = ItemBuilder::default();
- i.title(format!("Reply from {}", creator_name));
- let author_url = format!("{}/u/{}", protocol_and_hostname, creator_name);
+ i.title(format!("Reply from {creator_name}"));
+ let author_url = format!("{protocol_and_hostname}/u/{creator_name}");
i.author(format!(
- "/u/{} <a href=\"{}\">(link)</a>",
- creator_name, author_url
+ "/u/{creator_name} <a href=\"{author_url}\">(link)</a>"
));
let dt = DateTime::<Utc>::from_utc(*published, Utc);
i.pub_date(dt.to_rfc2822());
// If its a url post, add it to the description
if let Some(url) = p.post.url {
- let link_html = format!("<br><a href=\"{url}\">{url}</a>", url = url);
+ let link_html = format!("<br><a href=\"{url}\">{url}</a>");
description.push_str(&link_html);
}
let mut url = format!("{}image/process.{}?src={}", pictrs_config.url, format, name,);
if let Some(size) = params.thumbnail {
- url = format!("{}&thumbnail={}", url, size,);
+ url = format!("{url}&thumbnail={size}",);
}
url
};
Ok(s) => Ok(s),
Err(e) => Err(Error::new(
ErrorKind::Other,
- format!("Failed converting key to string: {}", e),
+ format!("Failed converting key to string: {e}"),
)),
};
Ok(Keypair {
impl Display for LemmyError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
if let Some(message) = &self.message {
- write!(f, "{}: ", message)?;
+ write!(f, "{message}: ")?;
}
writeln!(f, "{}", self.inner)?;
fmt::Display::fmt(&self.context, f)
-ARG RUST_BUILDER_IMAGE=clux/muslrust:1.64.0
+ARG RUST_BUILDER_IMAGE=clux/muslrust:1.67.0
FROM $RUST_BUILDER_IMAGE as chef
USER root
# Build the project
-FROM clux/muslrust:1.64.0 as builder
+FROM clux/muslrust:1.67.0 as builder
ARG CARGO_BUILD_TARGET=x86_64-unknown-linux-musl
ARG RUSTRELEASEDIR="release"
FROM alpine:3 as lemmy
# Install libpq for postgres
-RUN apk add libpq
+RUN apk update && apk add libpq
# Copy resources
COPY --from=builder /app/lemmy_server /app/lemmy
#!/bin/bash
set -e
-cargo clippy --workspace --fix --allow-staged --tests --all-targets --all-features -- \
+cargo clippy --workspace --fix --allow-staged --allow-dirty --tests --all-targets --all-features -- \
-D warnings -D deprecated -D clippy::perf -D clippy::complexity \
-D clippy::style -D clippy::correctness -D clippy::suspicious \
-D clippy::dbg_macro -D clippy::inefficient_to_string \
-D clippy::items-after-statements -D clippy::implicit_clone \
-D clippy::wildcard_imports -D clippy::cast_lossless \
-D clippy::manual_string_new -D clippy::redundant_closure_for_method_calls \
- -D clippy::unused_self
+ -D clippy::unused_self \
+ -A clippy::uninlined_format_args
then
cargo test -p $PACKAGE --all-features --no-fail-fast
else
- cargo test --workspace --all-features --no-fail-fast
+ cargo test --workspace --no-fail-fast
fi
# Add this to do printlns: -- --nocapture
info!("Running post_thumbnail_url_updates_2020_07_27");
- let domain_prefix = format!("{}/pictrs/image/", protocol_and_hostname,);
+ let domain_prefix = format!("{protocol_and_hostname}/pictrs/image/",);
let incorrect_thumbnails = post.filter(thumbnail_url.not_like("http%"));
}
// pre-formatting errors is a workaround for https://github.com/tokio-rs/tracing/issues/1565
- let display_error = format!("{}", response_error);
- let debug_error = format!("{:?}", response_error);
+ let display_error = format!("{response_error}");
+ let debug_error = format!("{response_error:?}");
tracing::info_span!(
parent: None,
reindex_aggregates_tables(&mut conn, true);
scheduler.every(1.hour()).run(move || {
let conn = &mut PgConnection::establish(&db_url)
- .unwrap_or_else(|_| panic!("Error connecting to {}", db_url));
+ .unwrap_or_else(|_| panic!("Error connecting to {db_url}"));
active_counts(conn);
update_banned_when_expired(conn);
reindex_aggregates_tables(conn, true);
fn reindex_table(conn: &mut PgConnection, table_name: &str, concurrently: bool) {
let concurrently_str = if concurrently { "concurrently" } else { "" };
info!("Reindexing table {} {} ...", concurrently_str, table_name);
- let query = format!("reindex table {} {}", concurrently_str, table_name);
+ let query = format!("reindex table {concurrently_str} {table_name}");
sql_query(query).execute(conn).expect("reindex table");
info!("Done.");
}