Skip to content
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

temporary pr to test fix #2626

Closed
wants to merge 4 commits into from
Closed
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
11 changes: 4 additions & 7 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,6 @@ jobs:
with:
prefix-key: ${{ env.RUST_CACHE_KEY }}

- name: Build
run: cargo build --workspace --locked

- name: Launch postgres
run: |
cp .env.sample .env
Expand All @@ -52,12 +49,12 @@ jobs:
# Make sure the database is actually working
psql "${DOCSRS_DATABASE_URL}"

- name: run database migrations
run: cargo run -- database migrate

- name: install SQLX CLI
run: cargo install sqlx-cli --no-default-features --features postgres

- name: run database migrations
run: cargo sqlx migrate run --database-url $DOCSRS_DATABASE_URL

- name: run sqlx prepare --check
run: just sqlx-check

Expand Down Expand Up @@ -99,7 +96,7 @@ jobs:
sleep 5
# Make sure the database is actually working
psql "${DOCSRS_DATABASE_URL}"

- name: run workspace tests
run: |
cargo test --workspace --locked --no-fail-fast
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ once_cell = { version = "1.4.0", features = ["parking_lot"] }
base64 = "0.22"
strum = { version = "0.26.1", features = ["derive"] }
lol_html = "1.0.0"
font-awesome-as-a-crate = { path = "crates/font-awesome-as-a-crate" }
dashmap = "6.0.0"
string_cache = "0.8.0"
zip = {version = "2.2.0", default-features = false, features = ["bzip2"]}
Expand Down Expand Up @@ -136,6 +135,7 @@ anyhow = { version = "1.0.42", features = ["backtrace"] }
grass = { version = "0.13.1", default-features = false }
once_cell = { version = "1.4.0", features = ["parking_lot"] }
syntect = { version = "5.0.0", default-features = false, features = ["parsing", "dump-create", "yaml-load", "regex-onig"] }
font-awesome-as-a-crate = { path = "crates/font-awesome-as-a-crate" }

[[bench]]
name = "compression"
Expand Down
189 changes: 188 additions & 1 deletion build.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
use anyhow::{Context as _, Error, Result};
use std::{env, path::Path};
use font_awesome_as_a_crate as f_a;
use std::{
env,
path::{Path, PathBuf},
};

mod tracked {
use once_cell::sync::Lazy;
Expand Down Expand Up @@ -80,11 +84,194 @@ fn main() -> Result<()> {
write_known_targets(out_dir)?;
compile_syntax(out_dir).context("could not compile syntax files")?;

println!("cargo::rustc-check-cfg=cfg(icons_out_dir)");
println!("cargo:rustc-cfg=icons_out_dir");

let out_css = "static/icons.css";
let out_css = if std::env::var("RUN_IN_DOCKER").is_ok() {
let _ = std::fs::create_dir_all("/srv/docsrs/static");
Path::new("/srv/docsrs/").join(out_css)
} else {
let package_dir = env::var("CARGO_MANIFEST_DIR").context("missing CARGO_MANIFEST_DIR")?;
Path::new(&package_dir).join(out_css)
};
generate_css_icons(out_css, out_dir)?;

// trigger recompilation when a new migration is added
println!("cargo:rerun-if-changed=migrations");
Ok(())
}

fn capitalize(s: &str) -> String {
let mut c = s.chars();
match c.next() {
None => String::new(),
Some(f) => f.to_uppercase().chain(c).collect(),
}
}

fn render_icon(
icon_name: &str,
icon_str: &str,
type_name: String,
code_output: &mut String,
css_output: &mut String,
icon_kind: &str,
) {
let css_class = format!("f-a_{icon_name}_{icon_kind}");
css_output.push_str(&format!(
"\
.{css_class} {{
--svg_{icon_name}_{icon_kind}: url('data:image/svg+xml,{icon_str}');
-webkit-mask: var(--svg_{icon_name}_{icon_kind}) no-repeat center;
mask: var(--svg_{icon_name}_{icon_kind}) no-repeat center;
}}
",
));
let type_name = format!("{type_name}{}", capitalize(icon_kind));
code_output.push_str(&format!(
r#"#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct {type_name};
impl {type_name} {{
pub fn render(&self, fw: bool, spin: bool, extra: &str) -> rinja::filters::Safe<String> {{
render({css_class:?}, fw, spin, extra)
}}
}}
"#,
));
}

fn generate_css_icons(css_path: PathBuf, out_dir: &Path) -> Result<()> {
let mut code_output = r#"pub(crate) mod icons {
fn render(
css_class: &str,
fw: bool,
spin: bool,
extra: &str,
) -> rinja::filters::Safe<String> {
let mut classes = vec!["fa-svg"];
if fw {
classes.push("fa-svg-fw");
}
if spin {
classes.push("fa-svg-spin");
}
if !extra.is_empty() {
classes.push(extra);
}
let icon = format!(
"<span class=\"{css_class} {class}\" aria-hidden=\"true\"></span>",
class = classes.join(" "),
);

rinja::filters::Safe(icon)
}"#
.to_string();
let mut css_output = r#".svg-clipboard {
/* This icon is copied from crates.io */
--svg-clipboard: url('data:image/svg+xml,<svg width="24" height="25" viewBox="0 0 24 25" fill="currentColor" xmlns="http://www.w3.org/2000/svg" aria-label="Copy to clipboard"><path d="M18 20h2v3c0 1-1 2-2 2H2c-.998 0-2-1-2-2V5c0-.911.755-1.667 1.667-1.667h5A3.323 3.323 0 0110 0a3.323 3.323 0 013.333 3.333h5C19.245 3.333 20 4.09 20 5v8.333h-2V9H2v14h16v-3zM3 7h14c0-.911-.793-1.667-1.75-1.667H13.5c-.957 0-1.75-.755-1.75-1.666C11.75 2.755 10.957 2 10 2s-1.75.755-1.75 1.667c0 .911-.793 1.666-1.75 1.666H4.75C3.793 5.333 3 6.09 3 7z"/><path d="M4 19h6v2H4zM12 11H4v2h8zM4 17h4v-2H4zM15 15v-3l-4.5 4.5L15 21v-3l8.027-.032L23 15z"/></svg>');
-webkit-mask: var(--svg-clipboard) no-repeat center;
mask: var(--svg-clipboard) no-repeat center;
}"#.to_string();

let brands: &[&dyn f_a::Brands] = &[
&f_a::icons::IconFonticons,
&f_a::icons::IconRust,
&f_a::icons::IconMarkdown,
&f_a::icons::IconGitAlt,
];
let regular: &[&dyn f_a::Regular] = &[
&f_a::icons::IconFileLines,
&f_a::icons::IconFolderOpen,
&f_a::icons::IconFile,
&f_a::icons::IconStar,
];
let solid: &[&dyn f_a::Solid] = &[
&f_a::icons::IconCircleInfo,
&f_a::icons::IconGears,
&f_a::icons::IconTable,
&f_a::icons::IconRoad,
&f_a::icons::IconDownload,
&f_a::icons::IconCubes,
&f_a::icons::IconSquareRss,
&f_a::icons::IconFileLines,
&f_a::icons::IconCheck,
&f_a::icons::IconTriangleExclamation,
&f_a::icons::IconGear,
&f_a::icons::IconX,
&f_a::icons::IconHouse,
&f_a::icons::IconCodeBranch,
&f_a::icons::IconStar,
&f_a::icons::IconCircleExclamation,
&f_a::icons::IconCube,
&f_a::icons::IconChevronLeft,
&f_a::icons::IconChevronRight,
&f_a::icons::IconFolderOpen,
&f_a::icons::IconLock,
&f_a::icons::IconFlag,
&f_a::icons::IconBook,
&f_a::icons::IconMagnifyingGlass,
&f_a::icons::IconLeaf,
&f_a::icons::IconChartLine,
&f_a::icons::IconList,
&f_a::icons::IconUser,
&f_a::icons::IconTrash,
&f_a::icons::IconArrowLeft,
&f_a::icons::IconArrowRight,
&f_a::icons::IconLink,
&f_a::icons::IconScaleUnbalancedFlip,
&f_a::icons::IconSpinner,
];

for icon in brands {
render_icon(
icon.icon_name(),
icon.icon_str(),
format!("{icon:?}"),
&mut code_output,
&mut css_output,
"brands",
);
}
for icon in regular {
render_icon(
icon.icon_name(),
icon.icon_str(),
format!("{icon:?}"),
&mut code_output,
&mut css_output,
"regular",
);
}
for icon in solid {
render_icon(
icon.icon_name(),
icon.icon_str(),
format!("{icon:?}"),
&mut code_output,
&mut css_output,
"solid",
);
}

std::fs::write(&css_path, css_output).map_err(|error| {
Error::msg(format!(
"Failed to write into `{}`: {error:?}",
css_path.display()
))
})?;

code_output.push('}');
let icons_file = out_dir.join("icons.rs");
std::fs::write(&icons_file, code_output).map_err(|error| {
Error::msg(format!(
"Failed to write `{}`: {error:?}",
icons_file.display()
))
})?;
Ok(())
}

fn write_git_version(out_dir: &Path) -> Result<()> {
let maybe_hash = get_git_hash()?;
let git_hash = maybe_hash.as_deref().unwrap_or("???????");
Expand Down
14 changes: 7 additions & 7 deletions crates/font-awesome-as-a-crate/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ If you have problems, [contact us](https://github.com/rust-lang/docs.rs/issues),
*/

use std::error::Error;
use std::fmt::{self, Display, Formatter};
use std::fmt::{self, Debug, Display, Formatter};

#[cfg(font_awesome_out_dir)]
include!(concat!(env!("OUT_DIR"), "/fontawesome.rs"));
Expand Down Expand Up @@ -94,18 +94,18 @@ pub trait IconStr {
fn icon_str(&self) -> &'static str;
}

pub trait Brands: IconStr {
fn get_type() -> Type {
pub trait Brands: IconStr + Debug {
fn get_type(&self) -> Type {
Type::Brands
}
}
pub trait Regular: IconStr {
fn get_type() -> Type {
pub trait Regular: IconStr + Debug {
fn get_type(&self) -> Type {
Type::Regular
}
}
pub trait Solid: IconStr {
fn get_type() -> Type {
pub trait Solid: IconStr + Debug {
fn get_type(&self) -> Type {
Type::Solid
}
}
Expand Down
1 change: 1 addition & 0 deletions dockerfiles/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ COPY assets assets/
COPY .sqlx .sqlx/
COPY migrations migrations/

ENV RUN_IN_DOCKER="1"
RUN cargo build --profile=$PROFILE

######################
Expand Down
5 changes: 4 additions & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ pub use self::registry_api::RegistryApi;
pub use self::storage::{AsyncStorage, Storage};
pub use self::web::{start_background_metrics_webserver, start_web_server};

pub(crate) use font_awesome_as_a_crate as f_a;
#[cfg(icons_out_dir)]
include!(concat!(env!("OUT_DIR"), "/icons.rs"));
#[cfg(not(icons_out_dir))]
include!("icons.rs");

mod build_queue;
pub mod cdn;
Expand Down
2 changes: 1 addition & 1 deletion src/web/crate_details.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1614,7 +1614,7 @@ mod tests {
.borrow()
.get("class")
.unwrap(),
"fa-svg"
"f-a_code-branch_solid fa-svg"
);

Ok(())
Expand Down
8 changes: 4 additions & 4 deletions src/web/csp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ impl Csp {
// the MIME type to allow loading favicons.
//
// Images from other HTTPS origins are also temporary allowed until issue #66 is fixed.
result.push_str("; img-src 'self' https:");
result.push_str("; img-src 'self' https: data:");

match content_type {
ContentType::Html => self.render_html(&mut result),
Expand Down Expand Up @@ -169,7 +169,7 @@ mod tests {
fn test_csp_other() {
let csp = Csp::new();
assert_eq!(
Some("default-src 'none'; base-uri 'none'; img-src 'self' https:".into()),
Some("default-src 'none'; base-uri 'none'; img-src 'self' https: data:".into()),
csp.render(ContentType::Other)
);
}
Expand All @@ -179,7 +179,7 @@ mod tests {
let csp = Csp::new();
assert_eq!(
Some(
"default-src 'none'; base-uri 'none'; img-src 'self' https:; \
"default-src 'none'; base-uri 'none'; img-src 'self' https: data:; \
style-src 'self' 'unsafe-inline'"
.into()
),
Expand All @@ -192,7 +192,7 @@ mod tests {
let csp = Csp::new();
assert_eq!(
Some(format!(
"default-src 'none'; base-uri 'none'; img-src 'self' https:; \
"default-src 'none'; base-uri 'none'; img-src 'self' https: data:; \
style-src 'self'; font-src 'self'; connect-src 'self'; script-src 'nonce-{}'",
csp.nonce()
)),
Expand Down
2 changes: 1 addition & 1 deletion src/web/page/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ pub(crate) struct GlobalAlert {
pub(crate) url: &'static str,
pub(crate) text: &'static str,
pub(crate) css_class: &'static str,
pub(crate) fa_icon: crate::f_a::icons::IconTriangleExclamation,
pub(crate) fa_icon: crate::icons::IconTriangleExclamationSolid,
}
Loading
Loading