This commit is contained in:
nora 2024-01-18 20:47:46 +01:00
parent 43d792e148
commit 89b3e2df37
13 changed files with 211 additions and 40 deletions

6
.gitignore vendored
View file

@ -1,2 +1,8 @@
# Cargo target dir
/target
# Custom Submodules
/submodules
# Resulting website
/dist

9
Cargo.lock generated
View file

@ -99,6 +99,12 @@ dependencies = [
"once_cell",
]
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "gimli"
version = "0.28.1"
@ -467,6 +473,9 @@ name = "website"
version = "0.1.0"
dependencies = [
"color-eyre",
"fs_extra",
"serde",
"serde_derive",
"toml",
"tracing",
"tracing-subscriber",

View file

@ -7,6 +7,9 @@ edition = "2021"
[dependencies]
color-eyre = "0.6.2"
fs_extra = "1.3.0"
serde = { version = "1.0.195", features = ["derive"] }
serde_derive = "1.0.195"
toml = "0.8.8"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.18", features = ["env-filter"] }

4
build.rs Normal file
View file

@ -0,0 +1,4 @@
fn main() {
let manifest = std::env::var("CARGO_MANIFEST_DIR").unwrap();
println!("cargo:rustc-env=ROOT_DIR={manifest}");
}

4
config.toml Normal file
View file

@ -0,0 +1,4 @@
[slides]
talks = [
"2024-01-17-how-to-contribute-to-the-rust-project"
]

View file

@ -1,3 +1,3 @@
{ pkgs ? import <nixpkgs> {} }: pkgs.mkShell {
packages = with pkgs; [ rustup ];
{ pkgs ? import <nixpkgs> { } }: pkgs.mkShell {
packages = with pkgs; [ rustup hugo ];
}

37
src/build/blog.rs Normal file
View file

@ -0,0 +1,37 @@
//! Builds my blog, built with hugo.
use std::{path::Path, process::Command};
use color_eyre::{eyre::Context, Result};
use crate::utils;
pub fn build(blog: &Path, dist: &Path) -> Result<()> {
info!("Building blog with hugo");
utils::run_process(
Command::new("git")
.args(&["submodule", "init"])
.current_dir(&blog),
)?;
utils::run_process(
Command::new("git")
.args(&["submodule", "update"])
.current_dir(&blog),
)?;
// Patch config
let config =
std::fs::read_to_string(blog.join("config.toml")).wrap_err("reading blog config")?;
let config = config.replace("baseURL = \"/\"", "baseURL = \"/blog/\"");
std::fs::write(blog.join("config.toml"), config).wrap_err("writing patched config.toml")?;
utils::run_process(
Command::new("hugo")
.args(&["--minify", "--destination", dist.to_str().unwrap()])
.current_dir(&blog),
)?;
Ok(())
}

22
src/build/mod.rs Normal file
View file

@ -0,0 +1,22 @@
//! This module assembles and builds the website.
mod blog;
mod slides;
use std::path::Path;
use color_eyre::{eyre::Context, Result};
use crate::Config;
pub fn assemble_website(config: &Config, submodules: &Path, dist: &Path) -> Result<()> {
blog::build(&submodules.join("blog"), &dist.join("blog")).wrap_err("building blog")?;
slides::build(
&config.slides,
&submodules.join("slides"),
&dist.join("slides"),
)
.wrap_err("building slides")?;
Ok(())
}

26
src/build/slides.rs Normal file
View file

@ -0,0 +1,26 @@
//! Moving the slides from the reveal.js repo
//! The setup is currently a bit bad but I'm not sure what the best solution would look like.
use std::path::Path;
use color_eyre::{eyre::WrapErr, Result};
use crate::{utils, SlidesConfig};
pub fn build(config: &SlidesConfig, slides: &Path, dist: &Path) -> Result<()> {
info!("Building slides");
debug!("Copying reveal.js dist");
utils::cp_r(&slides.join("dist"), &dist.join("dist")).wrap_err("copying reveal.js dist")?;
utils::cp_r(&slides.join("plugin"), &dist.join("plugin")).wrap_err("copying reveal.js dist")?;
for talk in &config.talks {
let path = slides.join(talk);
let dist = dist.join(talk);
utils::cp_r(&path, &dist).wrap_err("copying slide data")?;
}
Ok(())
}

View file

@ -1,22 +1,51 @@
mod build;
mod submodule;
mod utils;
#[macro_use]
extern crate tracing;
use std::path::Path;
use color_eyre::{eyre::Context, Result};
use serde::Deserialize;
use tracing_subscriber::EnvFilter;
fn main() -> Result<()> {
tracing_subscriber::fmt().with_env_filter(EnvFilter::from_default_env()).init();
const ROOT_DIR: &str = env!("ROOT_DIR");
let sub_config =
std::fs::read_to_string("submodules.toml").wrap_err("reading ./submodules.toml")?;
#[derive(Deserialize)]
struct Config {
slides: SlidesConfig,
}
#[derive(Deserialize)]
struct SlidesConfig {
talks: Vec<String>,
}
fn main() -> Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
let root = Path::new(ROOT_DIR);
// Set the current dir to nonsense to fail everything that relies on it
let _ = std::env::set_current_dir("/");
let config =
std::fs::read_to_string(root.join("config.toml")).wrap_err("reading config.toml")?;
let config = toml::from_str::<Config>(&config).wrap_err("parsing config.toml")?;
let sub_config = std::fs::read_to_string(root.join("submodules.toml"))
.wrap_err("reading submodules.toml")?;
let sub_config =
submodule::Submodules::parse(&sub_config).wrap_err("invalid submodules.toml")?;
submodule::sync(&sub_config).wrap_err("syncing subtrees")?;
let submodules_path = root.join("submodules");
submodule::sync(&submodules_path, &sub_config).wrap_err("syncing subtrees")?;
info!("Hello, world!");
let dist_path = root.join("dist");
build::assemble_website(&config, &submodules_path, &dist_path)?;
Ok(())
}

View file

@ -21,7 +21,7 @@
//! This module will check them out into a directory called `submodules` in the current directory.
//! Make sure to put this directory into `.gitignore`.
use std::{io, path, process};
use std::{path::Path, process};
use color_eyre::{
eyre::{Context, OptionExt},
@ -73,16 +73,10 @@ impl Submodules {
}
}
pub fn sync(config: &Submodules) -> color_eyre::Result<()> {
pub fn sync(path: &Path, config: &Submodules) -> color_eyre::Result<()> {
info!("Syncing submodules...");
let submodules_path = path::Path::new("submodules");
match std::fs::create_dir(submodules_path) {
Ok(()) => info!("Created ./submodules"),
Err(e) if e.kind() == io::ErrorKind::AlreadyExists => {}
e => return e.wrap_err("failed to create submodules"),
}
utils::create_dir_if_not_exist(path)?;
for sync in &config.configs {
let name = &sync.name;
@ -91,12 +85,12 @@ pub fn sync(config: &Submodules) -> color_eyre::Result<()> {
let span = info_span!("Syncing submodule", ?name, ?url);
let _span = span.enter();
let sub_path = submodules_path.join(name);
let sub_path = path.join(name);
if !sub_path.exists() {
info!(?name, ?url, "Cloning");
let mut cmd = process::Command::new("git");
cmd.args(&["clone", url, sub_path.to_str().unwrap()]);
utils::run_process(&mut cmd).wrap_err("running git clone")?;
utils::run_process(&mut cmd)?;
} else {
debug!(?name, ?url, "Repo already exists");
}
@ -123,16 +117,14 @@ pub fn sync(config: &Submodules) -> color_eyre::Result<()> {
"fetch",
"origin",
sync.commit.as_str(),
]))
.wrap_err("git fetch")?;
]))?;
}
utils::run_process(process::Command::new("git").current_dir(&sub_path).args(&[
"reset",
"--hard",
sync.commit.as_str(),
]))
.wrap_err("git reset --hard")?;
]))?;
}
}

View file

@ -2,20 +2,54 @@ use color_eyre::{
eyre::{bail, Context},
Result,
};
use std::process::Command;
use fs_extra::dir::CopyOptions;
use std::{path::Path, process::Command};
pub fn run_process(cmd: &mut Command) -> Result<String> {
let name = cmd.get_program().to_os_string();
let output = cmd
.output()
.wrap_err(format!("failed to spawn process {name:?}"))?;
fn run_process_inner(cmd: &mut Command) -> Result<String> {
let name = cmd.get_program().to_os_string();
let output = cmd
.output()
.wrap_err(format!("failed to spawn process {name:?}"))?;
if !output.status.success() {
bail!(
"command returned error: {}",
String::from_utf8(output.stderr).wrap_err("stderr is not UTF-8")?
);
if !output.status.success() {
bail!(
"command returned error: {}",
String::from_utf8(output.stderr).wrap_err("stderr is not UTF-8")?
);
}
Ok(String::from_utf8(output.stdout).wrap_err("stdout is not UTF-8")?)
}
Ok(String::from_utf8(output.stdout).wrap_err("stdout is not UTF-8")?)
run_process_inner(cmd).wrap_err(format!(
"{} {}",
cmd.get_program().to_str().unwrap(),
cmd.get_args()
.map(|arg| format!("'{}'", arg.to_str().unwrap()))
.collect::<Vec<_>>()
.join(" ")
))
}
pub fn create_dir_if_not_exist(p: &Path) -> Result<()> {
match std::fs::create_dir(p) {
Ok(()) => debug!(?p, "Created directory"),
Err(e) if e.kind() == std::io::ErrorKind::AlreadyExists => {}
e => return e.wrap_err("failed to create submodules"),
}
Ok(())
}
pub fn cp_r(from: &Path, to: &Path) -> Result<()> {
fs_extra::copy_items(
&[from],
to,
&CopyOptions {
overwrite: true,
copy_inside: true,
..CopyOptions::default()
},
)
.wrap_err(format!("copying to {}", to.display()))?;
Ok(())
}

View file

@ -2,3 +2,8 @@
name = "blog"
url = "https://github.com/Nilstrieb/nilstrieb.github.io.git"
commit = "a48053540e1bc85403c25526de304e82f5371a22"
[[submodule]]
name = "slides"
url = "https://github.com/Nilstrieb/slides.git"
commit = "0401f35c22b124b69447655f0c537badae9e223c"